首页 > 技术文章 > 安卓开发——WebView+Recyclerview文章详情页,解决高度问题

sw-code 2021-10-23 11:31 原文

安卓开发——WebView+Recyclerview文章详情页,解决高度问题

最近在写一个APP时,需要显示文章详情页,准备使用WebView和RecyclerView实现上面文章,下面评论。出现了WebView高度问题,WebView加载HTML格式数据,而非URL

  • 这里的WebView为自定义组件NestedScrollingWebView,已解决嵌套滑动问题。

  • 如果WebView设置为wrap_content,会出现下面的评论会在WebView渲染数据时提前显示在上面的情况,很不美观

  • 如果WebView设置为match_parent,当文章高度不足一屏时,下面空白太大,不美观。

案例

设置为wrap_content

设置为match_parent

设置为match_parent,不另设置高度

通过JS设置高度

解决方案

利用JS获取高度,然后通知(loadUrl(js))WebView改变高度。关于JS获取高度,这里采用了一种我觉得很准确的方法

private fun getHtmlData(title:String, bodyHTML: String): String {
    val head = ("<head>" +
                "<meta name=\"viewport\" " +
                "content=\"width=device-width, " +
                "initial-scale=1.0, user-scalable=no\"> " +
                "<style></style></head>")
    return "<html>$head<body>" +
    "<h2 class='title'>$title</h2>$bodyHTML<div class='bottom'></div>" +
    "</body></html>"
}

在文章内容的最下面加一个div,通过document.querySelector('.bottom').offsetTop来用于确定高度

具体方法

1、先创建一个Mobile

private inner class Mobile {
    @JavascriptInterface
    fun onGetWebContentHeight(height: Int) {
        contentWV.post {
            val layoutParams = contentWV.layoutParams
            layoutParams.height = Utils.getPixelByDp(this@JsSetHeightActivity, height)
            contentWV.layoutParams = layoutParams
            Log.i(TAG, "onGetWebContentHeight: height=$height")
        }
    }
}

2、在初始化WebView时,设置必要参数

private fun initView() {
    contentWV = findViewById<NestedScrollingWebView>(R.id.content_wv)

    // 开启js
    val setting = contentWV.settings
    setting.javaScriptEnabled = true

    // 添加JS接口
    val mobile = Mobile()
    contentWV.addJavascriptInterface(mobile, "mobile")

    // 在 onPageFinished时重新设置高度
    val webClient = object : WebViewClient() {
        override fun onPageFinished(view: WebView?, url: String?) {
            val js = "javascript:mobile.onGetWebContentHeight(document.querySelector('.bottom').offsetTop)"
            view?.loadUrl(js)
        }
    }
    contentWV.webViewClient = webClient
}

在页面加载完成之后,会重新设置高度

Demo下载

文章详情 Demo下载

参考

文中的WebView以及NestedScroll的用法参考:10分钟带你入门NestedScrolling机制 - SegmentFault 思否

其他实现方案:上面webview 下边评论 (applemei.com)

推荐阅读