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

时间:2015-07-02 14:59:14

标签: android

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

This is the correct way

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

Padding between items increasing

我有一个像这样的典型RecyclerView

DataTable()

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

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

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

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

这就是我的RecyclerViewItemDecoration类:

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

感谢您的帮助!

8 个答案:

答案 0 :(得分:13)

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

rv.removeItemDecoration(yourDecorator)

让我知道它是否有效!

答案 1 :(得分:8)

每次加载recyclerview时都会添加Decoration

改为使用一个标志:

private boolean flagDecoration = false;

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

答案 2 :(得分:1)

我遇到了同样的问题,最好的解决方案是在视图持有者中初始化布局管理器时进行项目装饰,这样可以解决您面临的问题 例子

public class GridViewHolder extends ViewHolder {

    RecyclerView grid_list;

    public GridViewHolder(View v) {
        super(v);
        this.grid_list = (RecyclerView) v.findViewById(R.id.home_screen_item_grid_recycler_view);
        if (grid_list.getLayoutManager() == null) {
            RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(context, 4);
            grid_list.setLayoutManager(mLayoutManager);
            grid_list.addItemDecoration(new GridSpacingItemDecoration(4, 3, false));
        }
    }
}

答案 3 :(得分:1)

面对同样的问题并通过放置

解决了这个问题
mLayoutManager = new LinearLayoutManager(current_activity);
recyclerView.setLayoutManager(mLayoutManager);

onPreExecute()方法中。

如果有效的话,试试吧

答案 4 :(得分:1)

我面临同样的问题。如果检查

,请修复此问题
    if (recyclerView.getItemDecorationAt(0) == null) { // check decoration here
        FlexboxItemDecoration agentDividerItemDecoration = new FlexboxItemDecoration(rv.getContext());
        agentDividerItemDecoration.setDrawable(recyclerView.getContext().getResources().getDrawable(R.drawable.shape_divider_flex_normal));
        recyclerView.addItemDecoration(agentDividerItemDecoration);
    } else {
        Log.i(TAG, "initTagsView: ItemDecoration not null");
    }

答案 5 :(得分:1)

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

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

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

答案 6 :(得分:0)

显然你正在添加各种装饰品。 我遇到了同样的问题。我在这里做了什么,结果是:

1º - 在onCreate()方法之前声明装饰:

public StickyHeaderDecoration mDecor;
public MyAdapterPinned MyAdapterPinned;

2º - 然后我创建了一个创建并填充我的recycleview的方法。在这个方法中,我检查我是否已经调用了mDecor。如果是这样,我将其删除。否则,我创建它。代码如下所示:

public void createRecyclerView(){
    //hide layout com progress
    hideLayoutProgressFull();

    LinearLayoutManager mLayoutManager = new 
    LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
    recyclerView.setLayoutManager(mLayoutManager);

    recyclerView.setItemAnimator(new DefaultItemAnimator());

    myAdapterPinned = new MyAdapterPinned(getContext(), mList);

    recyclerView.setAdapter(myAdapterPinned);

    if (mDecor != null)
        recyclerView.removeItemDecoration(mDecor);

    mDecor = new StickyHeaderDecoration(myAdapterPinned);
    recyclerView.addItemDecoration(mDecor);

    //hide progressDialog
    hideProgress();
}    

注意:我使用的是一个适配器,可以为每个更改设置标题,但不能干扰结果。您可以使用普通的适配器。它对我有用。我希望它也适合你;

答案 7 :(得分:0)

我遇到了同样的问题,并使用itemDecorationCount修复了该问题

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