WebView на китайских устройствах игнорирует принудительно установленный размер представления
У меня есть 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
Как видите, все значения равны, и это правильно.
Но на разных китайских устройствах (Xiaomi MiA1 Android 9, Lenovo 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
неверны и не изменяются при обновлении параметров макета.
Как исправить эту проблему?
1 ответ
Хорошо, это ошибка многих разных китайских устройств, по крайней мере, Xiaomi и Lenovo, начиная с Android 6.0 и заканчивая Android 10 (Android 5.0-5.1 в порядке).
Похоже, они скопировали тот же неправильный код в свои прошивки.