Android:正确删除视图并将其添加到recyclerView [英] Android: removing and adding views to a recyclerView properly

查看:213
本文介绍了Android:正确删除视图并将其添加到recyclerView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a simple RecyclerView that looks like a list, I'm setting each view a diffrent ID, and adding views by clicking on the first view, and removing views when they're clicked (expect the first one). What's not working correctly is when I remove a view and then add another one, the new view's ID breaks the order.

适配器

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个视图,请删除第二个视图,然后再添加另一个视图,它将再次添加第二个视图或第6个视图. 因此,我认为这里的问题是如何在删除视图后不回收视图?

My problem is, if I add 5 views, remove the 2nd, and then add another one, it will add the 2nd again isntead of a 6th. So I think the question here is how to not recycle the views after removing them?

推荐答案

RecyclerViews背后的想法是,您可以将在onCreateViewHolder()中提供的视图持有者重用于同一viewType的视图.这种行为是使RecyclerViews高效的原因-膨胀视图的成本很高,而运行findViewById的成本也很高.

The idea behind RecyclerViews is that the view holder you provide in onCreateViewHolder() may be reused for views of the same viewType. This behavior is what makes RecyclerViews efficient - it is expensive to inflate views, and expensive to run findViewById.

您没有覆盖getItemViewType,因此您的RecyclerView仅具有一种视图类型-即,当您滚动浏览多个视图并删除/添加视图时,ViewHolders可以自由地在彼此之间进行回收.

You did not override getItemViewType so your RecyclerView only has one viewtype -- i.e. your ViewHolders are free to be recycled amongst each other as you scroll across many views, and delete/add views.

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

So what is happening in your code? When you delete view number two, its ViewHolder is recycled, and sent back to the recycler view pool. When you add view number 6, the recycler view uses the recycled view holder from number 2. Thus, onCreateViewHolder is never called (because there was an extra view to recycle!). However, onBindViewHolder is called. So add a method to update the data displayed by the 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中调用此方法:

and call this method in onBindViewHolder:

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

这篇关于Android:正确删除视图并将其添加到recyclerView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆