Android app:layout_behavior 之后 NestedScrollView 的尺寸有误

Android NestedScrollView has wrong size after app:layout_behavior

自从 Google 发布了 android 的设计支持库后,无需实现自定义代码即可完成许多不错的事情。虽然我测试了这个库中的自定义视图,但我发现了一个更糟糕的事情,我不知道这是否是一个错误。

我在 github 上找到了 cheesesquare 项目。在activity_detail.xml(布局文件)中,NestedScrollView 中有 3 个 CardView。如果删除其中的 2 个,您可以看到 NestedScrollView 没有父级的完整大小(match_parent)。 NestedScrollView 绑定到父视图的底部。 http://i.stack.imgur.com/BXl7w.png

当我删除 app:layout_behavior="@string/appbar_scrolling_view_behavior" 时,NestedScrollView 得到了他的全尺寸。

但是当我删除布局行为时,工具栏没有折叠。

有什么解决办法吗?可以在此处找到示例布局文件:https://github.com/Smove/cheesesquare/blob/Whosebug/app/src/main/res/layout/activity_detail.xml

您可以从我的 github 分支 Whosebug

构建 cheesesquare apk

使用 RecyclerView 替换 NestedScrollView 修复此错误 设置项目计数 1,即 ViewHolder return 你的真实 contentView;

我的代码:

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);

    recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
    // 添加分割线
    recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext()));

    recyclerView.setAdapter(new Adapter<ViewHolder>() {

        @Override
        public int getItemCount() {
            return 1;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int arg1) {
            WebView view = (WebView) holder.itemView;
            view.getSettings().setJavaScriptEnabled(true);
            view.loadUrl("http://www.baidu.com");
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {
            return new ViewHolder(inflater.inflate(R.layout.webview, arg0, false)) {
            };
        }
    });

我遇到了这个问题并修复了添加:

android:layout_gravity="fill_vertical"

到 NestedScrollView。然后它开始正常运行,正如我解释的那样 也。当然 NestedScrollView 需要某种子类(即它不能为空),否则工具栏不会折叠。

更新

虽然这对小内容 很好 ,但我注意到它在显示较长的内容时存在一些问题,例如就像上面的完整 activity_detail.xml 一样。问题是您无法滚动到内容的最底部 - 它无法到达底部。

根据我的测试,我可以发现缺少的部分 与折叠的工具栏一样大 (或者至少在我看来是这样)。要解决这个问题,并有一个对大小内容都可靠的解决方案,您应该向 ScrollView 添加一个 layout_marginBottom,以便对其进行测量并 释放 丢失的内容底部。因此:

android:layout_gravity="fill_vertical"
android:layout_marginBottom="?attr/actionBarSize"

或您为 Toolbar 指定的任何尺寸。

但还是

使用此解决方案滚动小内容,即使内容在顶部恰好对齐,也不像滚动大内容那样流畅。在库修复出现之前,我会一直使用。

更新2

看起来这是在 v22.2.1 中修复的。

解决方法

在显示 NestedScrollView 之前以及将数据绑定到 NestedScrollView 内容之后,我使用 View.FOCUS_UP 方向作为参数调用 NestedScrollView 实例的方法 fullScroll(int direction)。

片段的代码示例:

NestedScrollView scrollView = (NestedScrollView) getActivity().findViewById(R.id.scroll_view); scrollView.fullScroll(View.FOCUS_UP);

使用@natario 的答案如果您改为为子项设置填充(在我的例子中是 LinearLayout),它看起来会更好:

<androidx.core.widget.NestedScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"
                android:layout_gravity="fill_vertical">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:paddingBottom="?attr/actionBarSize">
                <!--Rest of the code-->

或者在 Kotlin 中你可以这样做:

 coordinator.doOnLayout {
        nestedScrollView.minimumHeight = resources.displayMetrics.heightPixels - with(TypedValue().also {theme.resolveAttribute(android.R.attr.actionBarSize, it, true)}) {
            TypedValue.complexToDimensionPixelSize(data, resources.displayMetrics)}
    }

android:minHeight="?attr/actionBarSize" 添加到 CollapsingToolbarLayout