从" 23.1.1"升级支持库后,Recycler视图项填满整个回收站视图高度到" 23.2.1"

时间:2016-04-03 06:44:04

标签: android android-recyclerview android-support-library android-support-design

以前,我使用以下旧支持库" 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看起来像

的方式

enter image description here

现在,我希望迁移到" 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整个高度。

enter image description here

enter image description here

这是我的布局文件的代码段:https://gist.github.com/yccheok/241a0d38d56305a1be24d09b54eb1600

让我感到困惑的是,虽然我在回收商视图项目布局中使用"wrap_content",但它并没有按预期工作。

我没有为RecyclerView使用任何自定义布局管理器。

http://developer.android.com/tools/support-library/index.html开始,我意识到23.2.1这次对RecyclerView进行了大量修改。

  • 修复了与各种measure-spec方法相关的错误。 (问题201856)
  • 减少了RecyclerView在计算布局或滚动时不允许更改适配器的锁定时间。 (问题202046)
  • 修复了在视图不可用的项目上调用notifyItemChanged()时发生崩溃的问题。 (问题202136)
  • 修复了RecyclerView.LayoutManager在同一测量过程中添加和删除视图时发生的崩溃。 (问题193958)

我最怀疑的是https://code.google.com/p/android/issues/detail?id=201856,因为它涉及更改各种测量规范方法

到目前为止,我尝试使用简单的RecyclerView项目重现问题,使用23.2.1但是失败了!它没有"项目填满RecyclerView整个高度"问题。我的猜测是,我的简单项目并没有模拟我的生产项目的复杂布局结构。我的生产项目具有以下布局

<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);
    }

不幸的是,lastLayoutParamsnormalLayoutParams正在初始化为

    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解决问题。

7 个答案:

答案 0 :(得分:17)

更新

您似乎正在为LayoutParam中的View更新Adapter

可以说出这一点,因为在您开始滚动之前,您的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" />

确保你改变它们两个!

答案 1 :(得分:10)

我有类似的问题。它非常重视回收商不是问题。检查您的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

如果无效,您可以为视图项添加另一个设置minHeightmaxHeight的属性。

答案 2 :(得分:8)

好消息:

我可以确切地指出改变RecyclerView行为的确切版本:它不是23.2.1中的更改​​,而是23.2.0 (February 2016)中的更改。更具体地说:

  

RecyclerView.LayoutManager不再忽略一些   RecyclerView.LayoutParams设置,例如滚动中的MATCH_PARENT   方向。

     

注意:这些提升的限制可能会导致布局出现意外行为。确保指定正确的布局参数。

实际上,如果启动23.2.0库,您将看到相同的行为。在您的情况下,这种行为可以简化为:

现在,当你有使用android:layout_x="match_parent"的RecyclerView的孩子时,这将影响RecyclerView的android:layout_x,而这在23.1.1及更早版本中并非如此。

坏消息:

即使我99%确定这是您的问题背后的原因,我仍然无法在您的代码中看到问题。我实际上使用您的XML结构设置了一个RecyclerView(仅改变颜色/背景参数),使用LinearLayoutManager,它在23.2.1中按预期工作。如果您想进行健全性检查,我可以分享我的实施。

你应该仔细检查你的适配器实现/操作,即使它已经拉长了。

答案 3 :(得分:4)

要解决此错误, row_layout 应该有高度固定 wrap_content !我也有这个问题,只是意识到row_layout的高度是match_parent。

答案 4 :(得分:3)

回收视图的高度必须为&#34; wrap_content&#34;只要。如果单元格的大小增加,循环视图将处理高度。

<强> 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" />

答案 5 :(得分:2)

我认为这是有问题的路线:

<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。

答案 6 :(得分:1)

只需将row_layout高度设为wrap_content 所以它只占用所有物品的行实际高度空间。