HTML滚动事件在ScrollView内部的Android WebView中

Sha*_*evy 12 android webview android-scrollview

我有一个用于测试目的的网页(https://storage.googleapis.com/htmltestingbucket/nested_scroll_helper.html),它只打印html在固定标题中捕获的滚动事件的计数器

当Android WebView是片段中唯一可滚动的元素时,一切都很好,WebView将滚动事件发送到页面

如果我想在WebView的上方和下方添加原生元素,那么事情会变得复杂得多.

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="20dp"
            android:text="SOMETHING ABOVE THE WEBVIEW" />

        <WebView
            android:id="@+id/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="20dp"
            android:text="SOMETHING BELOW THE WEBVIEW" />

    </LinearLayout>
</ScrollView>
Run Code Online (Sandbox Code Playgroud)

我知道在ScrollView中使用WebView并不好,但我必须在html文档中提供混合内容和正确滚动事件的单一滚动体验.我发现了很多关于此事的问题,但我能够创建一个完整的端到端解决方案


此外,我知道lint有一个官方的检查:

NestedScrolling ---------------摘要:嵌套滚动小部件

优先级:7/10严重性:警告类别:正确性

滚动窗口小部件(如ScrollView)不应包含任何嵌套滚动窗口小部件,因为它具有各种可用性问题

然而,我无法在本机中实现Web视图内容,因此我需要另一种方法来实现

use*_*237 1

要将 Webview 保留在滚动视图中,您需要测量 WebView 的高度并将其设置在布局参数中。

在这里我试图给出可滚动网页视图的答案。

<ScrollView
        android:layout_width="fill_parent" android:background="#FF744931"
        android:layout_height="fill_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            tools:ignore="WebViewLayout">

            <TextView
                android:id="@+id/txtVoiceSeachQuery"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#FF0000"
                android:textSize="26sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="SOMETHING ABOVE THE WEBVIEW" />

            <com.example.ScrollableWebView
                android:id="@+id/webview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:isWebViewInsideScroll="true" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="SOMETHING BELOW THE WEBVIEW" />

        </LinearLayout>
    </ScrollView>
Run Code Online (Sandbox Code Playgroud)

资源/值/attrs.xml

为自定义控件添加属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ScrollableWebView">
    <attr name="isWebViewInsideScroll" format="boolean"></attr>
</declare-styleable>
</resources>
Run Code Online (Sandbox Code Playgroud)

可滚动WebView

public class ScrollableWebView extends WebView {
    private boolean webViewInsideScroll = true;
    public static final String RESOURCE_NAMESPACE = "http://schemas.android.com/apk/res-auto";

    public ScrollableWebView(Context context) {
        super(context);
    }

    public ScrollableWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setWebViewInsideScroll(attrs.getAttributeBooleanValue
                (RESOURCE_NAMESPACE, "isWebViewInsideScroll", true));
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (isWebViewInsideScroll()) {
            int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);
            ViewGroup.LayoutParams params = getLayoutParams();
            params.height = getMeasuredHeight();
            setLayoutParams(params);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    public boolean isWebViewInsideScroll() {
        return webViewInsideScroll;
    }

    public void setWebViewInsideScroll(boolean webViewInsideScroll) {
        this.webViewInsideScroll = webViewInsideScroll;
    }
}
Run Code Online (Sandbox Code Playgroud)

要获取属性值,您还可以使用 Stylable,但这里我没有使用它。

ScrollableWebView webview = (ScrollableWebView) findViewById(R.id.webview);
        webview.loadUrl("https://storage.googleapis.com/htmltestingbucket/nested_scroll_helper.html");
Run Code Online (Sandbox Code Playgroud)

以下是输出的链接

如果您不想创建属性文件并在 res/values/attrs.xml 中添加自定义属性,则可以忽略该文件并检查我在此处给出的没有任何自定义属性(例如isWebViewInsideScroll. 你也可以从 xml 布局中删除它。如果有的话请告诉我。