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的設置!!!)}

相關文章
相關標籤/搜索