Issue
I have a WebView, that adapts to its content height:
with(this.settings) {
javaScriptEnabled = true
allowFileAccess = true
displayZoomControls = false
builtInZoomControls = false
cacheMode = WebSettings.LOAD_NO_CACHE
layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL // Tried the default one
setSupportZoom(false)
}
isVerticalScrollBarEnabled = false
isHorizontalScrollBarEnabled = false
setBackgroundColor(Color.TRANSPARENT)
setLayerType(View.LAYER_TYPE_HARDWARE, null)
setWebViewClient(webViewClient)
clearCache(true)
addJavascriptInterface(this, "MathView")
private val webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
Timber.d("onPageFinished: $url")
invalidate()
loadUrl("javascript:MathView.resize(document.body.scrollHeight)")
}
override fun onPageCommitVisible(view: WebView?, url: String?) {
super.onPageCommitVisible(view, url)
// skip code
invalidate()
}
}
When the page loads, I call JS code with callback to find out content height:
@JavascriptInterface
fun resize(newContentHeight: Float) {
runOnMain {
val calculatedHeight = (newContentHeight * resources.displayMetrics.density).toInt()
val webViewContentHeight = (this.contentHeight * resources.displayMetrics.density).toInt()
Timber.d("Content height changed: $newContentHeight for content $htmlBody")
Timber.d("Calculated height: $calculatedHeight; current height: $height; webview content height: $webViewContentHeight")
if (calculatedHeight != lastCalculatedHeight) {
lastCalculatedHeight = calculatedHeight
Timber.d("Setting new height: $calculatedHeight")
updateLayoutParams {
height = lastCalculatedHeight
requestLayout()
invalidate()
}
}
}
}
// I also call this code once a second in the debug version to check the sizes.
On most devices it works fine:
Calculated height: 252; current height: 252; webview content height: 252
Calculated height
— content height reported by JS multiplied by screen densityCurrent height
— WebView (as an Android view) heightwebview content height
— content height reported by the WebView itself
As you can see, all values are equal, and that's correct.
But on the different Chinese devices (Xiaomi MiA1 Android 9, Lenovo P1a42 Android 6.0.1) it ignores layout updates and sets different view height:
// Note: this is different content then above, so calculated height is not equal to the above one
Calculated height: 315; current height: 567; webview content height: 567
Calculated heught
reported by the JS is correctCurrent height
andwebview content height
are not correct and they are not changed by the layout params update.
How to fix this problem?
Solution
Okay, it's a bug across lots of different Chinese devices, at least Xiaomi and Lenovo, starting from Android 6.0 to Android 10 (Android 5.0-5.1 is OK).
Seems that they copy-pasted the same incorrect code to their firmwares.
Answered By - artem
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.