博客 / 詳情

返回

WebView 嵌套滑動,絲滑般實現吸頂效果,完美兼容 X5 webview

背景

本文首發我的微信公眾號徐公,收錄於 Github·AndroidGuide,這裏有 Android 進階成長知識體系, 希望我們能夠一起學習進步,關注公眾號徐公,5 年中大廠程序員,一起建立核心競爭力

最近項目在開發中,需要實現 WebView 吸頂的效果。剛開始在 Demo 實現的時候,使用的是普通的 WebView。切換到項目的時候,由於使用的是 X5 WebView,在解決過程中。又遇到了一些問題,覺得挺有代表性的,就記錄了下來。

如果你也有相似的問題,可以參考這種思路解決。

實現原理簡述

講解之前,我們先來看一下效果圖

webview 嵌套滑動.gif

説到嵌套滑動,很多人第一時間都會想到 CoordinatorLayout behavior ,但是 webview 本身並不是 NestedScrollChild 的,無法實現。

於是,我們可以自己實現 NestedScrollChild 接口,去實現嵌套滑動。具體的實現原理,可以參照我的這一篇博客。

【原理篇】WebView 實現嵌套滑動,絲滑般實現吸頂效果,完美兼容 X5 webview

系統 webview 實現吸頂效果

第一步:引入我的開源庫

 implementation("io.github.gdutxiaoxu:nestedwebview:0.21")

第二步:藉助 CoordinatorLayout behavior 實現吸頂效果

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="MissingDefaultResource">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="250dp">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="?attr/colorPrimary"
            android:scaleType="fitXY"
            android:src="@drawable/tangyan"
            app:layout_scrollFlags="scroll" />

    </com.google.android.material.appbar.AppBarLayout>


    <io.github.gdutxiaoxu.nestedwebview.NestedWebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

X5 webview 實現吸頂效果

第一種方式

第一種方式,使用我封裝好的 NestedX5WebView,在佈局文件中指定 behavior

第一步:引入我的開源庫

implementation("io.github.gdutxiaoxu:nestedx5webview:0.21")

第二步:藉助 CoordinatorLayout behavior 實現吸頂效果

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="MissingDefaultResource">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        app:layout_behavior=".behavior.DisableAbleAppBarLayoutBehavior">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="?attr/colorPrimary"
            android:scaleType="fitXY"
            android:src="@drawable/tangyan"
            app:layout_scrollFlags="scroll" />

    </com.google.android.material.appbar.AppBarLayout>


    <io.github.gdutxiaoxu.nestedwebview.x5.NestedX5WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

第二種方式

使用騰訊的 WebView,在代碼當中動態指定 X5ProxyWebViewClientExtension 即可

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="MissingDefaultResource">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="250dp">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="?attr/colorPrimary"
            android:scaleType="fitXY"
            android:src="@drawable/tangyan"
            app:layout_scrollFlags="scroll" />

    </com.google.android.material.appbar.AppBarLayout>


    <com.tencent.smtt.sdk.WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

代理 X5 webview 相關的觸摸事件

        val x5CallBackClient = X5CallBackClient(webView.view, webView)
        webView.setWebViewCallbackClient(x5CallBackClient)
        webView.webViewClientExtension = X5ProxyWebViewClientExtension(x5CallBackClient)

更多吸頂效果

使用CoordinatorLayout打造各種炫酷的效果

自定義Behavior —— 仿知乎,FloatActionButton隱藏與展示

NestedScrolling 機制深入解析

一步步帶你讀懂 CoordinatorLayout 源碼

自定義 Behavior -仿新浪微博發現頁的實現

ViewPager,ScrollView 嵌套ViewPager滑動衝突解決

自定義 behavior - 完美仿 QQ 瀏覽器首頁,美團商家詳情頁

源碼地址

nestedwebview, 可以幫忙給個 star 哦。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.