webview 高度在 nestedScrollView 内无限增长

Posted

技术标签:

【中文标题】webview 高度在 nestedScrollView 内无限增长【英文标题】:webview height grows indefinitely inside a nestedScrollView 【发布时间】:2016-02-14 19:06:23 【问题描述】:

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

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

<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_
android:layout_
android:background="@android:color/black">

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

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

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbarlayout"
    android:layout_
    android:layout_
    android:layout_alignParentTop="true">

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

        <RelativeLayout
            android:layout_
            android:layout_
            android:background="#FFFFFF"
            android:descendantFocusability="beforeDescendants"
            android:focusableInTouchMode="true">

            <EditText
                android:id="@+id/current_url"
                android:layout_
                android:layout_
                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_
                android:layout_
                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 在所有手机和平板电脑中占据整个窗口。 当然可以,就像将窗口大小设置为webview一样简单,为什么你认为你不能? 我尝试将其设置为固定大小。硬编码和窗口大小。问题是 webview 不滚动。如果我有一个像 800dp 这样的硬编码值,webview 会显示一个网页更新 800dp 并在它之后剪掉这些东西。所以我无法看到它下面的部分。我根据不同的 SO 帖子尝试了类似的事情并且遇到了同样的问题。 Webview 不会加载超出设置大小的网页。我认为应该有一个更清洁的解决方案 webview 应该有自己的滚动条,应该像 firefox 一样,如果网页大于它应该有滚动条的窗口...你试过这个:setVerticalScrollBarEnabled(true);? 已启用。如果我删除了nestedScrollView,webview 按预期工作并且滚动工作 【参考方案1】:

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

如果您将WebView 放入NestedScrollView(或ScrollView)内,则您的WebView 将根据View.MeasureSpec.UNSPECIFIED 要求测量其尺寸。无论您为WebView 的高度设置MATCH_PARENT 还是固定尺寸(例如100dp)。 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 意味着,正如它的标签所暗示的,它可以是它想要的任何大小。我认为"Writing Custom Views for Android" session at Google I/O 2013 的这张幻灯片将帮助您理解它。

其实这是this thread讨论过的问题,根据this Google engineer,

这就像在桌面上一样,您将浏览器窗口的大小调整为页面的高度,使其无法垂直滚动。滚动发生在 NestedScrollView 而不是 webview 本身。所以页面中没有js的后果是看到任何滚动事件,所以不知道你已经滚动到页面末尾加载更多内容。

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

【讨论】:

但问题是,如果没有NestedScrollView,即使添加了app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior",底部的View也不会隐藏【参考方案2】:

对于没有提前结束这个问题,我深表歉意。我们不能将 webview 放在 nestedScrollView 中。但是 NSV 的本质是,它将其子级扩展到其全高,以便它可以使用工具栏按预期工作以获得可折叠/可滚动的工具栏等。因此,如果添加 webview,webview 将无限增长或增长到很大值,因此它不会按预期工作。这可以是参考:code.google.com/p/android/issues/detail?id=198965

【讨论】:

这正是我想指出的,另外WebView 中的缩放控制也会丢失。很遗憾没有解决方案。

以上是关于webview 高度在 nestedScrollView 内无限增长的主要内容,如果未能解决你的问题,请参考以下文章

如何在运行时更改 webview 的高度?

如何获取webView的高度

webview 高度在 nestedScrollView 内无限增长

swift 如何获取webView的内容高度

iOS野路子精准获取webView内容高度,自适应高度

ReactNative中将WebView放入ListView中高度自适应