在使用Webview进行滑动操作时,从屏幕可见区域外向内滑动时,会出现webview区域闪烁的问题(反之也是),本文将提供一种解决方案。
问题图示

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:overScrollMode="never"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="600dp"
android:background="@color/colorPrimary" />
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/contract_font"></WebView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
可以看到,NestedScrollView嵌套webview,且webview初始未在一屏内时,滑进出屏幕时会有短暂的白色块。
解决问题
方案对比
方案 | 考虑点 |
---|---|
android:hardwareAccelerated="false" | 5.0 开始Android系统为了充分利用GPU的特性,使得界面渲染更加平滑而默认开启的,如果关掉的话,那么整个网页不流畅了,岂不是得不偿失——>放弃 |
setBackgroundColor(Color.parseColor(“#00000000”)); setBackgroundResource(R.drawable.white); | 设置底色背景,但是webview本身是加载的H5页面,使用的是H5页面的底色背景,而且通过上面的gif可以看出,没有效果——>放弃 |
==通过样式布局,让webview保持在第一屏内初始化== | 本文尝试的方案 |
方案探索
1.xml布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:overScrollMode="never"
android:scrollbars="none">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/contract_font"></WebView>
<View
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="600dp"
android:background="@color/colorPrimary" />
</FrameLayout>
</android.support.v4.widget.NestedScrollView>
通过FrameLayout来叠加使得webview保持在第一屏内初始化,然后设置webview的padding,这样使得完整的H5内容是在ContentView下方显示。 但是——>webview设置padding根本无效!!!
怎么办呢?无论怎样也想不到为什么会如此,毕竟本身api的实现上是有些缺陷的(https://stackoverflow.com/questions/9170042/how-to-add-padding-around-a-webview )
2.解决问题
最终的解决方案则是通过注入js代码来控制H5的padding来解决。
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
contentView.post(new Runnable() {
@Override
public void run() {
contentViewHeight = px2dp(getApplicationContext(), contentView.getMeasuredHeight());
if (contentViewHeight > 0) {
webView.loadUrl("javascript:document.body.style.marginTop=\"" + contentViewHeight + "px\"; void 0");
}
}
});
}
});
看下猜想运行的结果:

打开网页编辑模式,查看body这块的样式:




只需要将这部分操作转换为对应的代码即可: 将上面的 webView.loadUrl("javascript:document.body.style.paddingTop="" + contentViewHeight + "px"; void 0"); 替换为:
webView.loadUrl("javascript:document.body.style.marginTop=\"" + contentViewHeight + "px\"; void 0");
3.运行效果

总结
整个方案的实现其实就两块: 1.布局,让webview在一屏内初始; 2.设置H5网页的margin-top或者padding-top;