Android Webview滑进出屏幕闪烁问题的解决方案

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

问题图示

在这里插入图片描述
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">

    <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根本无效!!!java

怎么办呢?不管怎样也想不到为何会如此,毕竟自己api的实现上是有些缺陷的(https://stackoverflow.com/questions/9170042/how-to-add-padding-around-a-webview )android

2.解决问题

最终的解决方案则是经过注入js代码来控制H5的padding来解决。web

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");
                        }
                    }
                });
            }
        });
复制代码

看下猜测运行的结果: api

在这里插入图片描述
H5的显示缺乏了顶部,这样看来padding是没有效果的。可是,为何会没有效果呢,难道设置padding有问题? 以后查看了上面嵌入的网页的源码查看了下(网页是网络上随便找的一个url): https://36kr.com/

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

在这里插入图片描述
能够看到要注入的js控制的样式这块是没有设置的。所以能够将padding-top的参数经过这里设置进去。

在这里插入图片描述
可是发现设置的该参数无效,是什么缘由呢?接着往下翻:
在这里插入图片描述
原来是body中控制了padding-top的最高级样式显示,因此element-style中设置无效。因此要么把这段注释掉,从新写入至element-style中,要么尝试设置margin-top的方法。这里采用后者的作法:
在这里插入图片描述
能够看到,网页顶部出现了设置好的marin-top空白的高度。

只须要将这部分操做转换为对应的代码便可: 将上面的 webView.loadUrl("javascript:document.body.style.paddingTop="" + contentViewHeight + "px"; void 0"); 替换为:ide

webView.loadUrl("javascript:document.body.style.marginTop=\"" + contentViewHeight + "px\"; void 0");
复制代码

3.运行效果

在这里插入图片描述
能够看到已经没有闪烁了。

总结

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

\color{red}{(备注:以上方案是针对H5网页style设置的状况来定制显示的,因此在选定该方案的时候要协调好和H5前端人员style的设置!!!)}

相关文章
相关标签/搜索