将支持库从“23.1.1”升级到“23.2.1”后,回收站视图项目填满整个回收站视图高度
Recycler view item fill up entire recycler view height after upgrading support library from "23.1.1" to "23.2.1"
以前,我使用以下旧支持库“23.1.1”。
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:preference-v7:23.1.1'
compile 'com.android.support:preference-v14:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
效果很好。这是我的 RecyclerView
的样子
现在,由于修复了一些错误,我希望迁移到“23.2.1”。
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:support-v4:23.2.1'
compile 'com.android.support:preference-v7:23.2.1'
compile 'com.android.support:preference-v14:23.2.1'
compile 'com.android.support:design:23.2.1'
compile 'com.android.support:recyclerview-v7:23.2.1'
然而,突然之间,我所有的 RecyclerView
项目,似乎填满了 RecyclerView
整个高度。
这是我的布局文件的代码片段:https://gist.github.com/yccheok/241a0d38d56305a1be24d09b54eb1600
真正让我困惑的是,尽管我在回收站视图项目布局中使用了 "wrap_content"
,但它并没有按预期工作。
我没有为我的 RecyclerView
使用任何自定义布局管理器。
从http://developer.android.com/tools/support-library/index.html开始,我发现这次23.2.1对RecyclerView
做了很多改动。
- 修复了与各种测量规范方法相关的错误。 (第 201856 期)
- 缩短了
RecyclerView
不允许在计算布局或滚动时更改适配器的锁定期。 (第 202046 期)
- 修复了对不在视图中的项目调用
notifyItemChanged()
时发生的崩溃。 (第 202136 期)
- 修复了
RecyclerView.LayoutManager
在同一测量过程中添加和删除视图时发生的崩溃。 (问题 193958)
我最怀疑的是 https://code.google.com/p/android/issues/detail?id=201856 ,因为它涉及更改 各种测量规范方法
到目前为止,我尝试用一个简单的 RecyclerView
项目重现问题,使用 23.2.1 但失败了!它没有 "item fills up the RecyclerView
entire height" 问题。我的猜测是,我的简单项目没有模拟我的生产项目的复杂布局结构。我的生产项目具有以下布局
<Activity>
<Fragment>
<View Pager>
<Fragment>
<RecyclerView />
</Fragment>
</View Pager>
</Fragment>
</Activity>
调试了几个小时后,我仍然找不到这个问题的根本原因,有什么提示吗?
谢谢。
我试过的
我曾尝试改变 RecyclerView
来自
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
至
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
一开始看起来不错。但是,当您执行滚动时,事情不会按预期工作:https://www.youtube.com/watch?v=U2EChFn6WkI
更新:我终于找到了根本原因
是我这边的错误!由于我需要为最后一行项目设置不同的边距,因此这是我的适配器代码。
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final List<TransactionSummary> transactionSummaries = buyArray.transactionSummaries;
if (position == transactionSummaries.size() - 1) {
holder.itemView.setLayoutParams(lastLayoutParams);
} else {
holder.itemView.setLayoutParams(normalLayoutParams);
}
不幸的是,lastLayoutParams
和 normalLayoutParams
被初始化为
normalLayoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
);
lastLayoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
);
使用LinearLayout.LayoutParams.WRAP_CONTENT
解决问题。
我遇到了类似的问题。最终是回收商不是问题所在。检查您的 CardView 项目测量是否转换为如下所示:
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
...
/>
如果您不使用 CardView,请确保您在适配器中用于视图的元素具有 android:layout_height="wrap_content"
而不是 match_parent
。
如果这不起作用,您可以为视图项添加另一个属性设置 minHeight
或 maxHeight
。
我认为这是有问题的行:
<View android:layout_width="1px"
android:layout_height="match_parent" <!--change this to wrap_content-->
android:background="?attr/buyPortfolioSeperatorBackground"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp" />
您的布局项中有 2 个位置 layout_height="match_parent"。您应该将它们都更改为 wrap_content.
更新
您似乎正在为 Adapter
中的 View
更新 LayoutParam
。
可以这么说,因为在您开始滚动之前,您的 UI 看起来绝对没问题。这意味着您的 XML 是正确的,因为它在您的 XML 布局文件中定义。
它在滚动开始后发生变化,这意味着您的 onBindViewHolder
实现中存在逻辑错误。这就是为什么向下滚动时出现错误,然后向上滚动时错误仍然存在的原因。
旧答案
你的问题是你的分流器出了问题:
<View
android:layout_width="1px"
android:layout_height="match_parent"
android:background="?attr/buyPortfolioSeperatorBackground"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp" />
出于测试目的,将其设置为:
<View
android:layout_width="1px"
android:layout_height="30dp"
android:background="?attr/buyPortfolioSeperatorBackground"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp" />
确保两个都改了!
好消息:
我可以向您指出更改 RecyclerView 行为的确切版本:这不是 23.2.1 中的更改,而是 23.2.0 (February 2016) 中的更改。更具体地说:
RecyclerView.LayoutManager no longer ignores some
RecyclerView.LayoutParams settings, such as MATCH_PARENT in the scroll
direction.
Note: These lifted restrictions may cause unexpected behavior in your layouts. Make sure you specify the correct layout parameters.
确实,如果您启动 23.2.0 库,您会看到相同的行为。在您的情况下,该行为可以简化为:
现在,当 RecyclerView 的子级 android:layout_x="match_parent"
时,这将影响 RecyclerView 的 android:layout_x
,而在 23.1.1 和更早版本中并非如此。
坏消息:
即使我 99% 确定这就是你的问题背后的原因,我仍然看不出你的代码有问题。实际上,我已经使用您的 XML 结构(仅更改 color/background 参数)和 LinearLayoutManager 设置了一个 RecyclerView,它在 23.2.1 中按预期工作。如果您想执行完整性检查,我可以分享我的实现。
你应该仔细检查你的适配器 implementation/manipulation 即使它被拉得太长了。
回收视图的高度只能是"wrap_content"。如果单元格的大小增加,回收视图将处理高度。
buy_portfolio_fragment.xml
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/buyPortfolioListViewBackground"
android:requiresFadingEdge="none"
android:scrollbars="vertical"
android:paddingTop="@dimen/default_tab_layout_height"
android:clipToPadding="false" />
只需将 row_layout
高度设为 wrap_content
所以所有项目只需要行实际高度space。
要修复此错误 row_layout 应该 fixed 或 wrap_content!我也有这个问题,刚刚意识到 row_layout 的高度是 match_parent.
以前,我使用以下旧支持库“23.1.1”。
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:preference-v7:23.1.1'
compile 'com.android.support:preference-v14:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
效果很好。这是我的 RecyclerView
的样子
现在,由于修复了一些错误,我希望迁移到“23.2.1”。
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:support-v4:23.2.1'
compile 'com.android.support:preference-v7:23.2.1'
compile 'com.android.support:preference-v14:23.2.1'
compile 'com.android.support:design:23.2.1'
compile 'com.android.support:recyclerview-v7:23.2.1'
然而,突然之间,我所有的 RecyclerView
项目,似乎填满了 RecyclerView
整个高度。
这是我的布局文件的代码片段:https://gist.github.com/yccheok/241a0d38d56305a1be24d09b54eb1600
真正让我困惑的是,尽管我在回收站视图项目布局中使用了 "wrap_content"
,但它并没有按预期工作。
我没有为我的 RecyclerView
使用任何自定义布局管理器。
从http://developer.android.com/tools/support-library/index.html开始,我发现这次23.2.1对RecyclerView
做了很多改动。
- 修复了与各种测量规范方法相关的错误。 (第 201856 期)
- 缩短了
RecyclerView
不允许在计算布局或滚动时更改适配器的锁定期。 (第 202046 期) - 修复了对不在视图中的项目调用
notifyItemChanged()
时发生的崩溃。 (第 202136 期) - 修复了
RecyclerView.LayoutManager
在同一测量过程中添加和删除视图时发生的崩溃。 (问题 193958)
我最怀疑的是 https://code.google.com/p/android/issues/detail?id=201856 ,因为它涉及更改 各种测量规范方法
到目前为止,我尝试用一个简单的 RecyclerView
项目重现问题,使用 23.2.1 但失败了!它没有 "item fills up the RecyclerView
entire height" 问题。我的猜测是,我的简单项目没有模拟我的生产项目的复杂布局结构。我的生产项目具有以下布局
<Activity>
<Fragment>
<View Pager>
<Fragment>
<RecyclerView />
</Fragment>
</View Pager>
</Fragment>
</Activity>
调试了几个小时后,我仍然找不到这个问题的根本原因,有什么提示吗?
谢谢。
我试过的
我曾尝试改变 RecyclerView
来自
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
至
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
一开始看起来不错。但是,当您执行滚动时,事情不会按预期工作:https://www.youtube.com/watch?v=U2EChFn6WkI
更新:我终于找到了根本原因
是我这边的错误!由于我需要为最后一行项目设置不同的边距,因此这是我的适配器代码。
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final List<TransactionSummary> transactionSummaries = buyArray.transactionSummaries;
if (position == transactionSummaries.size() - 1) {
holder.itemView.setLayoutParams(lastLayoutParams);
} else {
holder.itemView.setLayoutParams(normalLayoutParams);
}
不幸的是,lastLayoutParams
和 normalLayoutParams
被初始化为
normalLayoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
);
lastLayoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
);
使用LinearLayout.LayoutParams.WRAP_CONTENT
解决问题。
我遇到了类似的问题。最终是回收商不是问题所在。检查您的 CardView 项目测量是否转换为如下所示:
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
...
/>
如果您不使用 CardView,请确保您在适配器中用于视图的元素具有 android:layout_height="wrap_content"
而不是 match_parent
。
如果这不起作用,您可以为视图项添加另一个属性设置 minHeight
或 maxHeight
。
我认为这是有问题的行:
<View android:layout_width="1px"
android:layout_height="match_parent" <!--change this to wrap_content-->
android:background="?attr/buyPortfolioSeperatorBackground"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp" />
您的布局项中有 2 个位置 layout_height="match_parent"。您应该将它们都更改为 wrap_content.
更新
您似乎正在为 Adapter
中的 View
更新 LayoutParam
。
可以这么说,因为在您开始滚动之前,您的 UI 看起来绝对没问题。这意味着您的 XML 是正确的,因为它在您的 XML 布局文件中定义。
它在滚动开始后发生变化,这意味着您的 onBindViewHolder
实现中存在逻辑错误。这就是为什么向下滚动时出现错误,然后向上滚动时错误仍然存在的原因。
旧答案
你的问题是你的分流器出了问题:
<View
android:layout_width="1px"
android:layout_height="match_parent"
android:background="?attr/buyPortfolioSeperatorBackground"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp" />
出于测试目的,将其设置为:
<View
android:layout_width="1px"
android:layout_height="30dp"
android:background="?attr/buyPortfolioSeperatorBackground"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp" />
确保两个都改了!
好消息:
我可以向您指出更改 RecyclerView 行为的确切版本:这不是 23.2.1 中的更改,而是 23.2.0 (February 2016) 中的更改。更具体地说:
RecyclerView.LayoutManager no longer ignores some RecyclerView.LayoutParams settings, such as MATCH_PARENT in the scroll direction.
Note: These lifted restrictions may cause unexpected behavior in your layouts. Make sure you specify the correct layout parameters.
确实,如果您启动 23.2.0 库,您会看到相同的行为。在您的情况下,该行为可以简化为:
现在,当 RecyclerView 的子级 android:layout_x="match_parent"
时,这将影响 RecyclerView 的 android:layout_x
,而在 23.1.1 和更早版本中并非如此。
坏消息:
即使我 99% 确定这就是你的问题背后的原因,我仍然看不出你的代码有问题。实际上,我已经使用您的 XML 结构(仅更改 color/background 参数)和 LinearLayoutManager 设置了一个 RecyclerView,它在 23.2.1 中按预期工作。如果您想执行完整性检查,我可以分享我的实现。
你应该仔细检查你的适配器 implementation/manipulation 即使它被拉得太长了。
回收视图的高度只能是"wrap_content"。如果单元格的大小增加,回收视图将处理高度。
buy_portfolio_fragment.xml
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/buyPortfolioListViewBackground"
android:requiresFadingEdge="none"
android:scrollbars="vertical"
android:paddingTop="@dimen/default_tab_layout_height"
android:clipToPadding="false" />
只需将 row_layout
高度设为 wrap_content
所以所有项目只需要行实际高度space。
要修复此错误 row_layout 应该 fixed 或 wrap_content!我也有这个问题,刚刚意识到 row_layout 的高度是 match_parent.