Reputation: 11
Description
I've developed a React website using the Mantine UI framework, and it works seamlessly across various browsers and devices. Now, I'm trying to create an Android app using Jetpack Compose that displays a WebView of the website. However, I've encountered an issue where some Mantine UI components, such as modals and the sidebar, fail to render correctly in the Android Webview, but does work in a regular android browser like Chrome.
Problem Description:
The modal background blurs as expected, but the modal itself and all it's contents does not appear. This issue is specific to Android; the website functions properly in a regular browser and on iOS. Webview permissions have been granted, including allowing JavaScript, but the problem persists.
Here's the code I'm using to display the WebView:
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
WebView(context).apply {
setupWebView(this)
loadUrl("https://v6.mantine.dev/core/modal/")
}
}
)
Attempts and Observations:
I tried various different ways of implementing the built in Webview into my app to see if I could resolve the issue, but none worked. I've also ensured the Webview isn't missing any permissions that's preventing it from working.
I've explored alternative WebView options and tested Mozilla's Geckoview, which renders the Mantine UI components correctly. However, I'm struggling to integrate Geckoview into my project due to Gradle build configuration differences.
I used this guide to try implement it, but failed:
https://firefox-source-docs.mozilla.org/mobile/android/geckoview/consumer/geckoview-quick-start.html
My Gradle Build Configuration:
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
namespace = "com.myapp"
compileSdk = 34
defaultConfig {
applicationId = "com.myapp"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.activity:activity-compose:1.8.1")
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
implementation("androidx.compose.material:material-icons-extended:1.5.4")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}
Question:
I appreciate any insights, workarounds, or examples that could help resolve this problem. Thank you!
Upvotes: 1
Views: 2951
Reputation: 1011
You need to set layoutParams
AndroidView(
factory = { context ->
WebView(context).apply {
settings.domStorageEnabled = true
settings.javaScriptEnabled = true
webChromeClient = WebChromeClient()
webViewClient = WebViewClient()
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
},
update = {
it.loadUrl(url)
},
modifier = Modifier
.fillMaxWidth()
.weight(1f)
)
Upvotes: 0
Reputation: 3202
As I checked your problem. You are missing the one line settings.javaScriptEnabled = true
which causes the error. Because default it is false so JavaScript
will not work and React is also a part of JavaScript
.
I have checked below example in my emulator and it works and open the model dialog with content.
import android.graphics.Bitmap
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
@Composable
fun WebViewDemoScree() {
var backEnabled by remember { mutableStateOf(false) }
var webView: WebView? = null
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
WebView(context).apply {
webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView, url: String?, favicon: Bitmap?) {
backEnabled = view.canGoBack()
}
}
settings.javaScriptEnabled = true
loadUrl("https://v6.mantine.dev/core/modal/")
webView = this
}
}, update = {
webView = it
})
BackHandler(enabled = backEnabled) {
webView?.goBack()
}
}
Upvotes: 1