Search code examples
androidkotlinwebviewandroid-jetpack-compose

Android Webview using Jetpack Compose not respecting html and body 100% height


I'm having an issue with Jetpack Compose on Android 12 where I'm attempting to create a WebView whose contents fill the entire screen. For some reason even though the WebView itself seems to completely fill the screen according to the Layout Inspector in Android studio (for instance, it has a height of 811dp on a Pixel 5 emulator device running API 32), when I inspect the html and body elements in the actual HTML page in Chrome's inspector, they have a height of 0px even though I have set them to 100% height. Rather than being presented with a completely green background like I would imagine should happen in a normal browser window, I am left with a blank white page, where the div in the body has a height of 0, the body has a height of 0, and the html container itself also has a height of 0. When I query window.innerHeight in the Chrome JavaScript console though, I get a value of 811 which matches the height of the WebView in Android Studio's Layout Inspector. But when selecting the body element and querying getBoundingClientRect(), I get the following output:

bottom: 0
height: 0
left: 0
right: 393.0909118652344
top: 0
width: 393.0909118652344
x: 0
y: 0

Here is my sample code:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            WebViewScreen()
        }
    }
}

@Composable
fun WebViewScreen() {
    Box(modifier = Modifier.fillMaxSize()) {
        AndroidView(
            factory = { context ->
                WebView(context)
            },
            update = { webView ->
                val HTMLstring = "<!DOCTYPE html><html><head><style>html, body { margin: 0; padding: 0; height: 100%; }</style></head><body><div style='height: 100%; background-color: green;'></div></body><html>"
                val encodedHTML = Base64.getEncoder().encodeToString(HTMLstring.toByteArray())
                webView.loadData(encodedHTML, "text/html", "base64")
            },
            modifier = Modifier.matchParentSize()
        )
    }
}

Have I missed a modifier or something else that would define the height of the Webview inside the HTML document context itself?


Solution

  • You can handle the sizing as follows. I also changed the Base64 part to make it cleaner.

    @Composable
    fun WebViewScreen() {
        Box(modifier = Modifier.fillMaxSize()) {
            AndroidView(factory = {
                WebView(it).apply {
                    layoutParams = ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT
                    )
                }
            }, update = {
                val HTMLstring =
                    "<!DOCTYPE html><html><head><style>html, body { margin: 0; padding: 0; height: 100%; }</style></head><body><div style='height: 100%; background-color: green;'></div></body><html>"
                it.loadDataWithBaseURL(null, HTMLstring, "text/html", "utf-8", null)
            })
        }
    }