RecyclerView装饰器在刷新时添加额外的填充

Bas*_*sit 20 android

所以,在我的项目中实现RecyclerView时,我遇到了一个奇怪的问题.我有一个自定义装饰器来实现一致的顶部和底部填充以及元素之间相当不同的填充值.每当我点击刷新,即从后端获取数据并再次填充RecyclerView时,填充会增加,并且每次刷新时都会继续增加.

这是正确的方法

当我点击刷新(导致AsyncTask再次执行)时,项目之间的空间增加.并且每次刷新都会不断增加.

物品之间的填充增加

我有一个像这样的典型RecyclerView

<android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="false"
    android:focusableInTouchMode="false">
</android.support.v7.widget.RecyclerView>
Run Code Online (Sandbox Code Playgroud)

在RecyclerView中填充内容是CardView,具有以下布局:

<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/cv"
android:layout_marginLeft="9dp"
android:layout_marginRight="9dp"
>

    <RelativeLayout
        android:id="@+id/itemLinearTop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingTop="17dp"
        android:paddingRight="10dp"
        android:paddingLeft="10dp">

        <TextView
            android:id="@+id/tv1"
            android:textColor="@color/logo_black"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium" />


        <TextView
            android:id="@+id/tv2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/tv1"
            android:textColor="@color/logo_black"
            android:layout_alignParentRight="true"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <!-- More elements -->
    </RelativeLayout>
</android.support.v7.widget.CardView>
Run Code Online (Sandbox Code Playgroud)

我正在初始化和填充RecyclerView,如下所示:

// In PostExecute of AsyncTask
RecyclerView rv = (RecyclerView) rootView.findViewById(R.id.recyclerview);
RecycleViewAdapter adapter = new FuelPricesRecycleViewAdapter(data);
rv.setAdapter(adapter);
rv.addItemDecoration(new RecyclerViewItemDecoration(30, item_count - 1));
Run Code Online (Sandbox Code Playgroud)

这就是我的RecyclerViewItemDecoration类的样子:

public class RecyclerViewItemDecoration extends RecyclerView.ItemDecoration {
    private int space = 0;
    private int item_count = 0;
    private int ADDITIONAL_PADDING = 20;

    public RecyclerViewItemDecoration(int space, int item_count) {
        this.space = space;
        this.item_count = item_count;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if(parent.getChildPosition(view) != item_count)
             outRect.bottom = space;

         // Add top margin only for the first item to avoid double space between items
         if(parent.getChildPosition(view) == 0)
             outRect.top = space + ADDITIONAL_PADDING;
         if(parent.getChildPosition(view) == item_count)
             outRect.bottom = space + ADDITIONAL_PADDING;
     }
 }
Run Code Online (Sandbox Code Playgroud)

谢谢您的帮助!

yug*_*oid 14

您必须在重新设置新数据之前删除项目装饰.

rv.removeItemDecoration(yourDecorator)

如果有效,请告诉我!


cod*_*lor 10

Decoration每次加载recyclerview时都会添加.

请改用一个标志:

private boolean flagDecoration = false;

if(!flagDecoration)
{
    rv.addItemDecoration(new RecyclerViewItemDecoration(30, item_count - 1));
    flagDecoration = true;    
}
Run Code Online (Sandbox Code Playgroud)


Ele*_*sis 8

我有同样的问题,我用 itemDecorationCount 解决了这个问题

if (recyclerView.itemDecorationCount == 0) {
            val itemDecorator = DividerItemDecoration(activity, DividerItemDecoration.VERTICAL)
            itemDecorator.setDrawable(ContextCompat.getDrawable(activity, R.drawable.recycler_divider))
            recyclerView.addItemDecoration(itemDecorator)
        }
Run Code Online (Sandbox Code Playgroud)


Pan*_*mar 6

发生这种情况是因为我们试图将itemDecorator添加到已经添加了itemDecorator的回收器视图中,请先检查其是否已经存在,然后再不添加

if (0 == recyclerview.getItemDecorationCount()) {
recyclerview.addItemDecoration(new DividerItemDecoration(ContextCompat.getDrawable(getActivity(), R.drawable.divider)));
}
Run Code Online (Sandbox Code Playgroud)

这个0将是我们在回收站视图中拥有的itemDecorator的数量,大多数情况下,它将为0。