Add a Delete Button in a RecyclerView

11,552

You can add the ImageButton click listener in your onBindViewHolder() method:

@Override
public void onBindViewHolder(ListsDatabaseListHolder holder, final int position) {

    holder.name.setText(list.get(position).getName());
    holder.date.setText(list.get(position).getDate());

    holder.delete.setOnClickListener(new View.OnClickListener() {
          public void onClick(View v) {
              ListsDatabaseList theRemovedItem = list.get(position);
              // remove your item from data base
              list.remove(position);  // remove the item from list
              notifyItemRemoved(position); // notify the adapter about the removed item
          }
    });
}
Share:
11,552
Razor
Author by

Razor

Just a hardcore Russian programmer ...

Updated on July 28, 2022

Comments

  • Razor
    Razor almost 2 years

    I am trying to add a delete button which is supposed to delete an item in a database based on the position it has in the RecyclerView. I am struggling with this. Here is my layout file for the RecyclerView:

    <TextView
        android:id="@+id/layout_list_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:textStyle="bold"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    
    <TextView
        android:id="@+id/layout_list_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@+id/layout_list_name"
        android:layout_alignLeft="@+id/layout_list_name"
        android:layout_below="@+id/layout_list_name" />
    
    <ImageButton
        android:id="@+id/layout_list_delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:contentDescription="Delete"
        android:src="@drawable/icon_layout_delete_layout_item" />
    

    This is where I declare the onItemClick for the ImageButton which is the delete button:

    imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(getBaseContext(), "Delete hit!", Toast.LENGTH_SHORT).show();
            }
        });
    

    This is my RecyclerView listener class:

    private OnItemClickListener onItemClickListener;
    
    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }
    
    GestureDetector gestureDetector;
    
    public ListsDatabaseItemListener(Context context, OnItemClickListener listener) {
        onItemClickListener = listener;
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent motionEvent) {
                return true;
            }
        });
    }
    
    @Override
    public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
        View view = recyclerView.findChildViewUnder(motionEvent.getX(), motionEvent.getY());
    
        if (view != null && onItemClickListener != null && gestureDetector.onTouchEvent(motionEvent)) {
            onItemClickListener.onItemClick(view, recyclerView.getChildLayoutPosition(view));
    
            return true;
        }
        return false;
    }
    
    @Override
    public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
    
    }
    
    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    
    }
    

    And finally, here is my adapter class:

    List<ListsDatabaseList> list;
    
    public ListsDatabaseListAdapter(List<ListsDatabaseList> list) {
        this.list = list;
    }
    
    @Override
    public ListsDatabaseListHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_list, parent, false);
        ListsDatabaseListHolder holder = new ListsDatabaseListHolder(view);
    
        return holder;
    }
    
    @Override
    public void onBindViewHolder(ListsDatabaseListHolder holder, int position) {
        holder.name.setText(list.get(position).getName());
        holder.date.setText(list.get(position).getDate());
    }
    
    @Override
    public int getItemCount() {
        return list.size();
    }
    
    public static class ListsDatabaseListHolder extends RecyclerView.ViewHolder {
        TextView name;
        TextView date;
        ImageButton delete;
    
        public ListsDatabaseListHolder(View view) {
            super(view);
    
            this.name = (TextView) view.findViewById(R.id.layout_list_name);
            this.date = (TextView) view.findViewById(R.id.layout_list_date);
            this.delete = (ImageButton) view.findViewById(R.id.layout_list_delete);
        }
    }
    

    Any suggestions on how to achieve this?

  • Rami
    Rami about 8 years
    Try to comment the onInterceptTouchEvent of your RecyclerView, i think it consumes the event.
  • Razor
    Razor about 8 years
    I tried that. It only causes my app to crash. Is there any other method?
  • Razor
    Razor about 8 years
    The error is when I comment out the onInterceptTouchEvent, it has a return type of a boolean. I need to keep return false; in that event handler or my app won't compile. When I do that, this error: FATAL EXCEPTION: main java.lang.NullPointerException
  • Razor
    Razor about 8 years
    I got this onInterceptEventhandler from a tutorial. I'm not to sure why it's there but if it is not required and will resolve the problem, then by all means tell me a way I can get rid of it so it doesn't interfere with my delete imagebutton.
  • Rami
    Rami about 8 years
    Just remove the listener, and onInterceptTouchEvent() method (or make it always return false). Maybe in the tutorial he implemented this method to detect swipe events or sthg else.
  • Razor
    Razor about 8 years
    Thankyou Rami! My app works now. I will figure out the sqlite database part myself now.
  • Nikos T
    Nikos T about 4 years
    Hi , after notifyItemRemoved(position), you must call also notifyItemRangeChanged(position,getItemCount());