中国设备上的 WebView 忽略强制设置的视图大小
WebView on Chinese devices ignores forcely set view size
我有一个 WebView,可适应其内容高度:
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()
}
}
当页面加载时,我调用带有回调的 JS 代码来找出内容高度:
@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()
}
}
}
}
// 我也在调试版本中每秒调用一次这段代码来检查大小。
在大多数设备上运行良好:
Calculated height: 252; current height: 252; webview content height: 252
Calculated height
— JS报告的内容高度乘以屏幕密度
Current height
— WebView(作为 Android 视图)高度
webview content height
— WebView 本身报告的内容高度
如您所见,所有值都相等,这是正确的。
但是在不同的中文设备上(小米 MiA1 Android 9,联想 P1a42 Android 6.0.1)它会忽略布局更新并设置不同的视图高度:
// 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
JS报告的是正确的
Current height
和 webview content height
不正确,它们没有被布局参数更新更改。
如何解决这个问题?
好吧,这是一个跨许多不同中国设备的错误,至少是小米和联想,从 Android 6.0 到 Android 10(Android 5.0-5.1 没问题) .
他们似乎将相同的错误代码复制粘贴到他们的固件中。
我有一个 WebView,可适应其内容高度:
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()
}
}
当页面加载时,我调用带有回调的 JS 代码来找出内容高度:
@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()
}
}
}
}
// 我也在调试版本中每秒调用一次这段代码来检查大小。
在大多数设备上运行良好:
Calculated height: 252; current height: 252; webview content height: 252
Calculated height
— JS报告的内容高度乘以屏幕密度Current height
— WebView(作为 Android 视图)高度webview content height
— WebView 本身报告的内容高度
如您所见,所有值都相等,这是正确的。
但是在不同的中文设备上(小米 MiA1 Android 9,联想 P1a42 Android 6.0.1)它会忽略布局更新并设置不同的视图高度:
// 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
JS报告的是正确的Current height
和webview content height
不正确,它们没有被布局参数更新更改。
如何解决这个问题?
好吧,这是一个跨许多不同中国设备的错误,至少是小米和联想,从 Android 6.0 到 Android 10(Android 5.0-5.1 没问题) .
他们似乎将相同的错误代码复制粘贴到他们的固件中。