Android:正确删除和添加视图到recyclerView

时间:2016-04-16 16:54:09

标签: java android android-recyclerview

我有一个看似列表的简单RecyclerView,我将每个视图设置为不同的ID,通过单击第一个视图添加视图,并在单击它们时删除视图(期望第一个视图)。什么不能正常工作是当我删除一个视图然后添加另一个视图时,新视图的ID会破坏顺序。

适配器

public class AddEventsAdapter extends RecyclerView.Adapter<AddEventsAdapter.ViewHolder> {

   private List<String> items = new ArrayList<>();

    public void addItem(String name) {
        items.add(name);
        notifyItemInserted(items.size() - 1);
    }

    public void removeItem(int position) {
        items.remove(position);
        notifyItemRemoved(position);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.add_event_item, parent, false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    static int i;

    class ViewHolder extends RecyclerView.ViewHolder{

        public TextView eventName;
        public RelativeLayout theLayout;


        public ViewHolder(View itemView) {
            super(itemView);
            eventName = (TextView)itemView.findViewById(R.id.eventName);
            theLayout = (RelativeLayout)itemView.findViewById(R.id.backgroundevent);

            theLayout.setId(++i);
            eventName.setText(String.format("", i));

            theLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (v.getId() == 1){
                    addItem("");
                }else {
                    removeItem(getAdapterPosition());
                }
            }
        });
        }
    }
}

实施:

    final AddEventsAdapter AddContainer = new AddEventsAdapter();
    AddEventsRecycler.setLayoutManager(new LinearLayoutManager(this));
    AddEventsRecycler.setAdapter(AddContainer);
    AddEventsRecycler.setItemViewCacheSize(666);

    AddContainer.addItem("");

每一行的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/event_clicked_ripple"
    android:clickable="true"
    android:id="@+id/backgroundevent"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp">

    <TextView
        android:clickable="false"
        android:id="@+id/eventName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="something"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@+id/eventImage"
        android:layout_toStartOf="@+id/eventImage"
        android:layout_marginRight="10dp"/>

    <ImageButton
        android:clickable="false"
        android:id="@+id/eventImage"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:background="@drawable/oval_shape"/>

</RelativeLayout>

我的问题是,如果我添加5个视图,删除第2个,然后添加另一个,它将再次添加第二个而不是第6个。 所以我认为这里的问题是如何在删除后回收视图?

2 个答案:

答案 0 :(得分:1)

RecyclerViews背后的想法是,您在onCreateViewHolder()中提供的视图持有者可能会被重用于同一viewType的视图。这种行为使RecyclerViews变得高效 - 浏览视图代价高昂,运行findViewById代价高昂。

您没有覆盖getItemViewType,因此您的RecyclerView只有一种视图类型 - 即滚动浏览多个视图并删除/添加视图时,您的ViewHolders可以互相回收。

那么您的代码中发生了什么?删除第二个视图时,其ViewHolder将被回收,并发送回回收站视图池。当您添加视图编号6时,回收站视图将使用编号为2的回收视图持有者。因此,永远不会调用onCreateViewHolder(因为有一个额外的视图要回收!)。但是,onBindViewHolder 调用。因此,添加一个方法来更新ViewHolder显示的数据:

 public void setData(final int position) {
    eventName.setText(String.format("", position));
    theLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (position == 1){
                addItem("");
            }else {
                removeItem(position);
            }
        }
}

并在onBindViewHolder中调用此方法:

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
     holder.setData(position);
}

答案 1 :(得分:0)

尝试将removeItem(int position)更改为

public void removeItem(int position) {
    items.remove(position);
    notifyItemRemoved(position);
    notifyItemRangeChanged(position, items.size());
}

它很可能会解决您的问题