Recycler view item fill up entire recycler view he

2019-01-31 17:11发布

Previously, I'm using the following old support libraries "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'

It works pretty well. Here's how my RecyclerView looks like

enter image description here

Now, I wish to migrate to "23.2.1", due to some bug fixes done.

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'

However, suddenly, all my RecyclerView items, seem to fill up the RecyclerView entire height.

enter image description here

enter image description here

Here's the code snippet of my layout file : https://gist.github.com/yccheok/241a0d38d56305a1be24d09b54eb1600

What really puzzle me is that, although I'm using "wrap_content" in my recycler view item layout, it doesn't work as expected.

I don't use any custom layout manager for my RecyclerView.

From http://developer.android.com/tools/support-library/index.html, I realize 23.2.1 makes quite a number of changes on RecyclerView this time.

  • Fixed bugs related to various measure-spec methods. (Issue 201856)
  • Reduced the lockdown period in which RecyclerView does not allow adapter changes while calculating a layout or scroll. (Issue 202046)
  • Fixed a crash when calling notifyItemChanged() on an item that is out of view. (Issue 202136)
  • Fixed a crash that occurs when RecyclerView.LayoutManager adds and removes a view in the same measurement pass. (Issue 193958)

What I suspect most is https://code.google.com/p/android/issues/detail?id=201856 , as it involves changing various measure-spec methods

So far, I try to reproduce the problem with a simple RecyclerView project, with 23.2.1 but failed! It doesn't have "item fills up the RecyclerView entire height" problem. My guess is that, my simple project doesn't simulate the complex layout structure of my production project. My production project is having the following layout

<Activity>
    <Fragment>
        <View Pager>
            <Fragment>
                <RecyclerView />
            </Fragment>
        </View Pager>
    </Fragment>
</Activity>

After debugging for few hours, I'm still cannot find root cause for such problem, any hint?

Thanks.

What I had tried

I had tried to change RecyclerView

from

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

to

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

It looks good initially. However, when you perform scrolling, thing doesn't work as expected : https://www.youtube.com/watch?v=U2EChFn6WkI

UPDATE: I finally figure out the root cause

Is mistake at my side! Since I need to have different margin for the last row item, here's my adapter code.

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

Unfortunately, lastLayoutParams and normalLayoutParams is being initialized as

    normalLayoutParams = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.MATCH_PARENT
    );

    lastLayoutParams = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.MATCH_PARENT
    );

Using LinearLayout.LayoutParams.WRAP_CONTENT solve the problem.

7条回答
何必那么认真
2楼-- · 2019-01-31 17:51

The good news:

I can pinpoint you to the exact version that changed RecyclerView's behavior: it's not a change in 23.2.1 but rather a change in 23.2.0 (February 2016). More specifically:

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.

Indeed if you fire up the 23.2.0 libraries, you will see the same behavior. That behavior can be simplified in your case as:

Now, when you have RecyclerView's children with android:layout_x="match_parent", that will affect RecyclerView's android:layout_x, which was not the case in 23.1.1 and earlier versions.

The bad news:

Even if I'm 99% sure that this is the reason behind your problem, I still can't see an issue in your code. I've actually set up a RecyclerView with your XML structure (changing just the color/background parameters), with a LinearLayoutManager and it works as expected in 23.2.1. I can share my implementation if you want to perform a sanity check.

You should double check your adapter implementation/manipulation even if it's far-stretched.

查看更多
登录 后发表回答