Android 从 RecyclerView 中删除行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26673444/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 12:03:30  来源:igfitidea点击:

Remove row from RecyclerView

androidandroid-5.0-lollipopandroid-recyclerview

提问by Pedro Oliveira

I have somehow implemented recycle view with the help of this post, now my requirement is to remove a row at runtime from this Recycle View.

在这篇文章的帮助下,我以某种方式实现了回收视图,现在我的要求是在运行时从此回收视图中删除一行。

link - http://treyrobinson.net/blog/android-l-tutorials-part-3-recyclerview-and-cardview/

链接 - http://treyrobinson.net/blog/android-l-tutorials-part-3-recyclerview-and-cardview/

Please help me.

请帮我。

Thanks.

谢谢。

回答by Pedro Oliveira

Since we don't know how is your adaper and given the info in that link you can create a method in the adapter that removes an object:

由于我们不知道您的 adaper 情况如何,并且根据该链接中的信息,您可以在适配器中创建一个删除对象的方法:

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

You can all this from your activity like:

您可以从您的活动中获得所有这些,例如:

((MyRecyclerAdapter)myRecyclerView.getAdapter()).removeItem(position);

回答by Mightian

I was able to make it work like this.

我能够让它像这样工作。

 ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
                //Remove swiped item from list and notify the RecyclerView
                datalist.remove(viewHolder.getAdapterPosition());
                // this line animates what happens after delete
                adapter.notifyItemRemoved(viewHolder.getAdapterPosition());
                Snackbar.make(recyclerView, "delete successful", Snackbar.LENGTH_LONG).show();
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }
        };

and set the above to the recycler view like this.

并将上述内容设置为这样的回收者视图。

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);

回答by Daniel Reina

If you want to remove a row by clicking on it, I think the cleaner way to do it is by implementing the onClicks at the ViewHolder. Then you implement a public remove method on the adapter, and then pass the adapter to the ViewHolder through the onCreateViewHolder method.

如果您想通过单击删除一行,我认为更简洁的方法是在 ViewHolder 上实现 onClicks。然后你在适配器上实现一个公共的remove方法,然后通过onCreateViewHolder方法将适配器传递给ViewHolder。

Would be something like this:

会是这样的:

---EXAMPLE---

- -例子 - -

Adapter:

适配器:

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {

private List<Object> mDataset; // This is the list of items to be shown    
//Here you would write the rest of your Adapter code

    public myViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        final View itemView = mInflater.inflate(R.layout.item_recyclerview_round, parent, false);
        return new RoundViewHolder(itemView, this);
    }

    public void removeItem(int position) {
        mDataSet.remove(position);
        notifyItemRemoved(position);
        // Add whatever you want to do when removing an Item
    }
}

ViewHolder:

视图持有人:

public class MyViewHolder RecyclerView.ViewHolder 
    implements View.OnClickListener {

    private MyAdapter myAdapter;
    // Here you would write the rest of your ViewHolder code

    public MyViewHolder (View itemView, MyAdapter myAdapter){
        super(itemView);
        this.myAdapter = myAdapter;
        // Here you would write the rest of your constructor
    }

    public void onClick(View view) {
        myAdapter.removeItem(getAdapterPosition());
    }

It works for me. I don't know if the performance could be improved (probably), but it is the simplest way I found.

这个对我有用。我不知道性能是否可以提高(可能),但这是我发现的最简单的方法。

I hope it helps.

我希望它有帮助。

回答by Piyush Kukadiya

I was trying the same thing from last 2 days and finally got it work.

我从过去 2 天开始尝试同样的事情,终于成功了。

My major problem was How to get position of clicked view so that we can remove it from adapter ?

我的主要问题是如何获取单击视图的位置以便我们可以将其从适配器中删除?

and solution was use holder.itemView.setTag(model.get(position));in onBindViewHolderto store position of view and get the clicked view's position by using ViewModel model = (ViewModel) v.getTag();in onClick()

而解决办法是使用holder.itemView.setTag(model.get(position));onBindViewHolder向观景店位置,并通过获取单击视图的位置 ViewModel model = (ViewModel) v.getTag();onClick()

Steps to remove row from RecyclerViewat runtime :

RecyclerView在运行时删除行的步骤:

  1. Create MainActivity.java

    public class MainActivity extends Activity {
    
        private RecyclerView  recyclerView;
        private RecyclerView.LayoutManager layoutManager;
        private String[] liststring;
        private TypedArray listImages;
        MyRecyclerView adapter;
        List<ViewModel> model;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            liststring=getResources().getStringArray(R.array.listString);
            listImages=getResources().obtainTypedArray(R.array.listImages);
    
    
            recyclerView=(RecyclerView) findViewById(R.id.my_recycler_view);
            recyclerView.setHasFixedSize(true);
            layoutManager=new LinearLayoutManager(this);
            recyclerView.setLayoutManager(layoutManager);
            adapter=new MyRecyclerView(createMockList(),this);
            recyclerView.setAdapter(adapter);
            adapter.setOnItemClickListener(new RecyclerViewItemClickInterface() {
    
                @Override
                public void onItemclick(View v,ViewModel vModel) {
                    // TODO Auto-generated method stub
                    Log.i("inflatedlayout", v.getId()+"");
                     adapter.remove(vModel);
                }
            });
            }
    
         private List<ViewModel> createMockList() {
             List<ViewModel> items = new ArrayList<ViewModel>();
             for (int i = 0; i < 9; i++) {
            items.add(new ViewModel("Item " + (i + 1),listImages.getResourceId(i, -1)));
             }
             return items;
             }
          }  
    
  2. create MyRecyclerView.java

    public class MyRecyclerView extends RecyclerView.Adapter<MyRecyclerView.MyViewHolder> implements View.OnClickListener { String data[]; TypedArray images; MyRecyclerView mv; Activity act_context; RecyclerViewItemClickInterface listener; List<ViewModel> model;

    public MyRecyclerView(List<ViewModel> model,Activity act_context) {
        // TODO Auto-generated constructor stub
        this.model=model;
        this.act_context=act_context;
    }
    
    public static class MyViewHolder extends ViewHolder{
    
        private ImageView imageView1;
        private TextView textView1;
        //private IMyViewHolderClicks listener;
    
        public MyViewHolder(View inflatedView) {
            super(inflatedView);
            // TODO Auto-generated constructor stub         
            textView1=(TextView) inflatedView.findViewById(R.id.textView1);
            imageView1=(ImageView) inflatedView.findViewById(R.id.imageView1);
        }
    }
    
    @Override
    public int getItemViewType(int position) {
        // TODO Auto-generated method stub
        Log.i("getIemViewTypePosition", ""+position);
        return super.getItemViewType(position);
        }
    
    @Override
    public int getItemCount() {
        // TODO Auto-generated method stub
        return model.size();
    }
    
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        // TODO Auto-generated method stub
    
        holder.itemView.setTag(model.get(position));
        holder.imageView1.setImageResource(model.get(position).getImage());
        holder.textView1.setText(model.get(position).gettest());
        Log.i("onBindViewHolder", "called by layoutmanager");
    }
    
    @Override
    public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
        // TODO Auto-generated method stub
        View v=LayoutInflater.from(act_context).inflate(R.layout.row_layout, parent, false);
        v.setOnClickListener(this);
        MyRecyclerView.MyViewHolder vh = new MyViewHolder(v);
        Log.i("onCreateViewHolder", "ViewHolder created");
        return vh;
    }
    
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
         if (listener != null) {
             ViewModel model = (ViewModel) v.getTag();
        listener.onItemclick(v,model);}
    }
    
    void setOnItemClickListener(RecyclerViewItemClickInterface listener){
    
        this.listener=listener;
    }
    
    public void remove(ViewModel item) {
        int position = model.indexOf(item);
        model.remove(position);
        notifyItemRemoved(position);
        }
    
    }    
    
  3. Create ViewModel.java

  1. 创建 MainActivity.java

    public class MainActivity extends Activity {
    
        private RecyclerView  recyclerView;
        private RecyclerView.LayoutManager layoutManager;
        private String[] liststring;
        private TypedArray listImages;
        MyRecyclerView adapter;
        List<ViewModel> model;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            liststring=getResources().getStringArray(R.array.listString);
            listImages=getResources().obtainTypedArray(R.array.listImages);
    
    
            recyclerView=(RecyclerView) findViewById(R.id.my_recycler_view);
            recyclerView.setHasFixedSize(true);
            layoutManager=new LinearLayoutManager(this);
            recyclerView.setLayoutManager(layoutManager);
            adapter=new MyRecyclerView(createMockList(),this);
            recyclerView.setAdapter(adapter);
            adapter.setOnItemClickListener(new RecyclerViewItemClickInterface() {
    
                @Override
                public void onItemclick(View v,ViewModel vModel) {
                    // TODO Auto-generated method stub
                    Log.i("inflatedlayout", v.getId()+"");
                     adapter.remove(vModel);
                }
            });
            }
    
         private List<ViewModel> createMockList() {
             List<ViewModel> items = new ArrayList<ViewModel>();
             for (int i = 0; i < 9; i++) {
            items.add(new ViewModel("Item " + (i + 1),listImages.getResourceId(i, -1)));
             }
             return items;
             }
          }  
    
  2. 创建 MyRecyclerView.java

    public class MyRecyclerView extends RecyclerView.Adapter<MyRecyclerView.MyViewHolder> implements View.OnClickListener { String data[]; TypedArray images; MyRecyclerView mv; Activity act_context; RecyclerViewItemClickInterface listener; List<ViewModel> model;

    public MyRecyclerView(List<ViewModel> model,Activity act_context) {
        // TODO Auto-generated constructor stub
        this.model=model;
        this.act_context=act_context;
    }
    
    public static class MyViewHolder extends ViewHolder{
    
        private ImageView imageView1;
        private TextView textView1;
        //private IMyViewHolderClicks listener;
    
        public MyViewHolder(View inflatedView) {
            super(inflatedView);
            // TODO Auto-generated constructor stub         
            textView1=(TextView) inflatedView.findViewById(R.id.textView1);
            imageView1=(ImageView) inflatedView.findViewById(R.id.imageView1);
        }
    }
    
    @Override
    public int getItemViewType(int position) {
        // TODO Auto-generated method stub
        Log.i("getIemViewTypePosition", ""+position);
        return super.getItemViewType(position);
        }
    
    @Override
    public int getItemCount() {
        // TODO Auto-generated method stub
        return model.size();
    }
    
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        // TODO Auto-generated method stub
    
        holder.itemView.setTag(model.get(position));
        holder.imageView1.setImageResource(model.get(position).getImage());
        holder.textView1.setText(model.get(position).gettest());
        Log.i("onBindViewHolder", "called by layoutmanager");
    }
    
    @Override
    public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
        // TODO Auto-generated method stub
        View v=LayoutInflater.from(act_context).inflate(R.layout.row_layout, parent, false);
        v.setOnClickListener(this);
        MyRecyclerView.MyViewHolder vh = new MyViewHolder(v);
        Log.i("onCreateViewHolder", "ViewHolder created");
        return vh;
    }
    
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
         if (listener != null) {
             ViewModel model = (ViewModel) v.getTag();
        listener.onItemclick(v,model);}
    }
    
    void setOnItemClickListener(RecyclerViewItemClickInterface listener){
    
        this.listener=listener;
    }
    
    public void remove(ViewModel item) {
        int position = model.indexOf(item);
        model.remove(position);
        notifyItemRemoved(position);
        }
    
    }    
    
  3. 创建 ViewModel.java

public class ViewModel {
String test; int image;
public ViewModel(String test,int image) { // TODO Auto-generated constructor stub this.test=test; this.image=image; }
String gettest(){ return test; }
int getImage(){ return image; }}

public class ViewModel {
String test; int image;
public ViewModel(String test,int image) { // TODO Auto-generated constructor stub this.test=test; this.image=image; }
String gettest(){ return test; }
int getImage(){ return image; }}

4.Create interface:

4.创建interface

interface RecyclerViewItemClickInterface {

void    onItemclick(View v,ViewModel viewModel);

}

回答by Yeahia2508

I know it's late answer but maybe it will be helpful for others. You don't need to add new delete method in your adapter class. Best way to do this, first add interfacein your ViewHolderclass.

我知道这是迟到的答案,但也许对其他人有帮助。You don't need to add new delete method in your adapter class. 做到这一点的最佳方法,首先add interface在你的ViewHolder班级。

public class ApapterVH extends RecyclerView.ViewHolder implements View.OnClickListener{
    ImageView ivDeleteItem;

    ApapterVH(View itemView) {
        super(itemView);

        ivDeleteItem = itemView.findViewById(R.id.ivDelete);

        itemView.setOnClickListener(this);
        ivDeleteFoodItem.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if(v.getId() == ivDeleteItem.getId()){
            onItemClickListener.onDelete(v, getAdapterPosition());
        }
        if(onItemClickListener!=null){
            onItemClickListener.onItemClick(v, getAdapterPosition());
        }
    }
}

public interface OnItemClickListener {
    void onItemClick(View view , int position);
    void onDelete(View view, int position);
}

public void SetOnItemClickListener(final OnItemClickListener onItemClickListener){
    this.onItemClickListener = onItemClickListener;
}

Then in your Activity or Fragment add this:

然后在您的 Activity 或 Fragment 中添加以下内容:

 mAdapter.SetOnItemClickListener(new YourAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(View view, int position) {
            //Do something
        }

        @Override
        public void onDelete(View view, int position) {
            mList.remove(position);
            mAdapter.notifyItemRemoved(position);
        }

    });

Only this two line code will delete your item :

只有这两行代码会删除您的项目:

 mList.remove(position);
 mAdapter.notifyItemRemoved(position);

回答by Kishan Solanki

If above solutions didn't work then try this,

如果上述解决方案不起作用,请尝试此操作,

private fun removeItem(position: Int) {
    items.removeAt(position)
    notifyItemRemoved(position)
    notifyItemRangeChanged(position, itemCount - position)
}