webview 高度在 nestedScrollView 内无限增长

webview height grows indefinitely inside a nestedScrollView

这是我的布局。当我加载 google.com 时,webview 的高度会无限增长。 webview 的 onSizeChange 函数不断被调用,我可以看到 webview 不断扩展。我已经尝试了 22.2.1 和 23.1.0 的设计和 appcompat 库,但没有效果。

有什么解决办法吗? :-|

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black">

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="fill_vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <com.example.ajay.scrollabletoolbar.MyWebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"/>
</android.support.v4.widget.NestedScrollView>

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbarlayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true">

    <android.support.v7.widget.Toolbar
        android:id="@+id/restricted_browser_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize"
        android:background="@color/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#FFFFFF"
            android:descendantFocusability="beforeDescendants"
            android:focusableInTouchMode="true">

            <EditText
                android:id="@+id/current_url"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_centerVertical="true"
                android:backgroundTint="@android:color/darker_gray"
                android:dropDownAnchor="@+id/restricted_browser_toolbar"
                android:hint="hint hint"
                android:imeOptions="actionGo|flagNoExtractUi"
                android:inputType="textNoSuggestions|textUri"
                android:paddingBottom="8dp"
                android:paddingEnd="8dp"
                android:paddingStart="8dp"
                android:singleLine="true"/>

            <ImageView
                android:id="@+id/clear_url_text"
                android:layout_width="48dp"
                android:layout_height="48dp"
                android:layout_alignRight="@+id/current_url"
                android:layout_centerVertical="true"
                android:layout_marginRight="8dp"
                android:src="@android:drawable/ic_menu_close_clear_cancel"
                android:visibility="gone"/>
        </RelativeLayout>
    </android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>

一句话,你只是不能把你的WebView放在NestedScrollView里面。这是按预期工作。

如果您将 WebView 放入 NestedScrollView(或 ScrollView)中,您的 WebView 将使用 View.MeasureSpec.UNSPECIFIED requirement. No matter you set MATCH_PARENT or even fixed size like 100dp for your WebView's height. NestedScrollView forces its children measure themselves with View.MeasureSpec.UNSPECIFIED requirement. It all happens at NestedScrollView's measureChild() 方法测量其尺寸。它如下所示:

@Override
protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
    ViewGroup.LayoutParams lp = child.getLayoutParams();
    int childWidthMeasureSpec;
    int childHeightMeasureSpec;
    childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, getPaddingLeft()
            + getPaddingRight(), lp.width);
    childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}

MeasureSpec.UNSPECIFIED意味着,正如它的标签所暗示的,它可以是任何它想要的大小。我认为来自 "Writing Custom Views for Android" session at Google I/O 2013 的这张幻灯片将帮助您理解它。

实际上这是在 this thread, and according to this Google engineer

中讨论过的问题

This is as if in desktop, you resize the browser window to height of the page so it can't scroll vertically. The scrolling is happening in NestedScrollView rather than webview itself. So a consequence of no js in the page sees any scroll events, so it doesn't know you've scrolled to the end of the page load more content.

所以,底线是,不要将你的 WebView 放在 NestedScrollView 中。您应该让 WebView 滚动网页本身。编码愉快! :)

很抱歉没有早点关闭这个问题。我们不能将 webview 放在 nestedScrollView 中。但是 NSV 的性质,它将其子级扩展到其全高,以便它可以按预期使用工具栏工作以获得 collapsible/scrollable 工具栏等。因此,如果添加了 webview,则 webview 将无限期增长或增长到一个很大的价值,因此它不会按预期工作。这可以是参考:code.google.com/p/android/issues/detail?id=198965