WebView在NestedScrollView中高度无限增长。

12
这是我的布局。当我加载google.com时,webview的高度会无限增长。webview的onSizeChange函数不断被调用,我可以看到webview无限扩展。我尝试了22.2.1和23.1.0的design和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>


1
我认为我不能使用固定大小。我希望WebView在所有手机和平板电脑中都占据整个窗口。 - onusopus
当然可以,就像将窗口大小设置为Webview一样简单,你为什么认为你不能呢? - Nanoc
我尝试将其设置为固定大小。硬编码和窗口大小。问题是WebView不会滚动。如果我有一个像800dp这样的硬编码值,WebView会显示一个网页更新800dp并在其后剪切掉一些内容。所以我无法看到它下面的部分。我根据不同的SO帖子尝试了类似的事情,并遇到了同样的问题。WebView不会加载超出设置大小的网页。我认为应该有一个更清晰的解决方案。 - onusopus
WebView 应该有自己的滚动条,行为应像 Firefox 一样,如果网页大于窗口,则应具有滚动条。你尝试过这个吗:setVerticalScrollBarEnabled(true)? - Nanoc
已启用。如果我删除嵌套的滚动视图,Webview 就会按预期工作,并且滚动也会正常。 - onusopus
显示剩余4条评论
2个回答

11
在一句话中,您无法将WebView放入NestedScrollView中。这是预期的工作方式。
如果您将WebView放入NestedScrollView(或ScrollView)中,则WebView会使用View.MeasureSpec.UNSPECIFIED要求测量其尺寸。无论您将MATCH_PARENT或甚至固定高度如100dp设置为WebView的高度,NestedScrollView都会强制其子项使用View.MeasureSpec.UNSPECIFIED的要求进行测量。这一切发生在NestedScrollViewmeasureChild()方法中。它的执行过程如下:
@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 的意思是,顾名思义,它可以是任何大小。我认为来自"Google I/O 2013 Writing Custom Views for Android" session的这张幻灯片会帮助你理解它。

enter image description here

实际上,这是一个在this thread中讨论过的问题,根据this Google engineer的说法,这就像在桌面上将浏览器窗口大小调整为页面高度,以便无法垂直滚动。滚动发生在NestedScrollView而不是webview本身中。因此,页面中没有js看到任何滚动事件的结果,所以它不知道您已经滚动到页面底部来加载更多内容。因此,最重要的是不要WebView放在NestedScrollView中。您应该让WebView自己滚动网页。祝编码愉快! :)

1
但问题在于,如果没有NestedScrollView,即使您已经添加了app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" ,底部视图也不会隐藏。 - Sam Chen

1

很抱歉没有早些关闭这个问题。我们不能在嵌套的滚动视图中放置Webview。但是,由于NSV的性质,它会将其子项扩展到其完整高度,以便可以使用工具栏实现可折叠/可滚动的工具栏等预期效果。因此,如果添加Webview,则Webview将无限增长或增长到较大值,因此它将无法按预期工作。这可能是一个参考:code.google.com/p/android/issues/detail?id=198965


这正是我想指出的,而且在 WebView 中缩放控制也会消失。很遗憾没有解决方案。 - Sam Chen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接