【问题标题】:Remove row from RecyclerView从 RecyclerView 中删除行
【发布时间】:2014-10-31 11:18:57
【问题描述】:

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

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

请帮帮我。

谢谢。

【问题讨论】:

  • 向我们展示您的适配器,以便我们更好地帮助您。

标签: android android-5.0-lollipop android-recyclerview


【解决方案1】:

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

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

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

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

【讨论】:

  • 不错且简洁的解决方案,但在大多数情况下(如果回收器行具有执行某些操作的按钮),单击事件将在适配器内的 ViewHolder 类中处理。因此,将此 removeItem() 方法添加到您的适配器,并使您的 ViewHolder 类实现 onClickListener 接口,并在您的 ViewHolder 类的重写 onClick 方法中处理单击事件。此外,如果您要从数据库中填充回收站视图,请不要忘记删除相应的数据库记录。
  • 我不同意。 ViewHolder,正如它的名字所指出的,它只是一个视图持有者。它不应该包含任何业务逻辑或点击逻辑。它只是视图模型的映射器。
  • 好的,如果每个回收站有多个按钮,你如何处理点击?
  • 您在 onCreateView 方法中创建了多个点击侦听器。查看我的博文了解更多信息androidshenanigans.blogspot.pt/2015/02/…
【解决方案2】:

我能够让它像这样工作。

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

并像这样将上述设置为回收站视图。

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

【讨论】:

    【解决方案3】:

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

    应该是这样的:

    ---示例---

    适配器:

    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());
        }
    

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

    希望对你有帮助。

    【讨论】:

      【解决方案4】:

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

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

      解决方案是在onBindViewHolder 中使用holder.itemView.setTag(model.get(position)); 来存储视图的位置,并通过在onClick() 中使用ViewModel model = (ViewModel) v.getTag(); 来获取点击视图的位置

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

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

      4.创建interface

      interface RecyclerViewItemClickInterface {
      
      void    onItemclick(View v,ViewModel viewModel);
      
      }
      

      【讨论】:

        【解决方案5】:

        我知道这是迟到的答案,但也许对其他人有帮助。 You don't need to add new delete method in your adapter class。最好的方法是,首先在 ViewHolder 类中使用 add interface

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

        然后在您的 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);
                }
        
            });
        

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

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

        【讨论】:

          【解决方案6】:

          如果上述解决方案不起作用,那么试试这个,

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-11-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-13
            • 2019-05-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多