安卓开发-解决WebView+Recyclerview实现文章详情页的高度问题
最近在写一个APP时,需要显示文章详情页,准备使用WebView和RecyclerView实现上面文章,下面评论。出现了WebView高度问题,WebView加载HTML
格式数据,而非URL
。
- 这里的
WebView
为自定义组件NestedScrollingWebView
,已解决嵌套滑动问题。
问题1
如果WebView设置为wrap_content
,可能由于网络和性能会出现文章加载没有评论快,导致评论会在WebView渲染数据时提前显示在上面的情况,很不美观。
点击查看问题
问题2
如果WebView设置为match_parent
,当文章高度不足一屏时,下面空白太大,不美观。
点击查看问题
解决方案
效果
可以先看一下效果
点击查看效果
思路
利用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)
val setting = contentWV.settings setting.javaScriptEnabled = true
val mobile = Mobile() contentWV.addJavascriptInterface(mobile, "mobile")
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)