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
自从 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
使用 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。然后它开始正常运行,正如我解释的那样
更新
虽然这对小内容 很好 ,但我注意到它在显示较长的内容时存在一些问题,例如就像上面的完整 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