Webview not properly sized Jetpack compose (Autosizing Webview Composable)

1.9k Views Asked by At

I need to use WebView in place of Text composable (to display complex text and maths). Size of the WebView will depend on amount of content(text). But currently it only works when a fixed size modifier is applied. Without fixed size; WebView stutters while loading and many times it wont even show up.

I am loading content using loadWithBaseUrl() method. I have tried using WebView composable from Accompanist library; Also tried my custom implementation; but it still wont work.

// implementation 'com.google.accompanist:accompanist-webview:0.24.3-alpha'

    LazyColumn(){
        item {
            val webViewState = rememberWebViewStateWithHTMLData(data = FakeData.HTML_DOC)
            Surface(
                modifier = Modifier.padding(8.dp, 8.dp).height(IntrinsicSize.Min)
            ) {
                WebView(
                    state = webViewState,
                    modifier = Modifier
//                        .size(400.dp, 200.dp)  // When fixed size applied problem disappears
                )
            }
        }

    }
1

There are 1 best solutions below

0
On

Use custom AccompanistWebViewClient, override onPageFinished, you can get webPage height by evaluateJavascript.

val jsWebHeight = "(function() {\n" +
                        "\tvar body = document.body,\n" +
                        "\thtml = document.documentElement;\n" +
                        "\tvar height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);\n" +
                        "\tvar width = html.scrollWidth;\n" +
                        "\tif (width > 0) return height;\n" +
                        "\telse return 0;\n" +
                        "})();"
override fun onPageFinished(view: WebView?, url: String?) {
     super.onPageFinished(view, url)

     view?.let{ webView ->
          val width = webView.width
          if (width > 0) {
               webView.evaluateJavascript(jsWebHeight) { result ->
                    result?.toIntOrNull()?.let { height ->
                         if (height > 0) {
                              // set webView height here, height is dp unit
                         }
                    }
               }
          }
     }
}