Bharath Chandra
Bharath Chandra

Reputation: 31

How to place onClickListeners for views inside the items of recyclerview?

I am working with recyclerview and sqlite database. i want to place a button in cardview such that whenever user clicks on that button, the respective record should be deleted from the table.
This is my adapter class for recyclerview

public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder> {
private Context mContext;
private Cursor mCursor;
private butttonsAdapetrListener mlistener;
private RecyclerView.ViewHolder v;
public CardAdapter(Context context, Cursor cursor ,butttonsAdapetrListener listener){
    mContext=context;
    mCursor=cursor;
    mlistener=listener;
}

@NonNull
@Override
public CardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(mContext);
    View view = inflater.inflate(R.layout.mycard,parent,false);
    return new CardViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull CardViewHolder holder, int position) {
    if(!mCursor.moveToPosition(position)){
        return;
    }
String name = mCursor.getString(mCursor.getColumnIndex("NAME"));
    int total = mCursor.getInt(mCursor.getColumnIndex("TOTAL"));
    int bunked = mCursor.getInt(mCursor.getColumnIndex("BUNK"));
    int color = mCursor.getInt(mCursor.getColumnIndex("COLOR"));
    long id= mCursor.getLong(mCursor.getColumnIndex("_id"));
    holder.nameText.setText(name);
    holder.totalText.setText(Integer.toString(total));
    holder.bunkedText.setText(Integer.toString(bunked));
    holder.colorText.setBackgroundColor(color);
    holder.itemView.setTag(id);
    v=holder;
}
@Override
public int getItemCount() {
    return mCursor.getCount();
}

public class CardViewHolder extends RecyclerView.ViewHolder{
    public TextView nameText;
    public TextView totalText;
    public TextView bunkedText;
    public TextView colorText;
    public Button delete;
    public CardViewHolder(@NonNull View itemView) {
        super(itemView);
        nameText= itemView.findViewById(R.id.name);
        totalText = itemView.findViewById(R.id.total_num);
        bunkedText = itemView.findViewById(R.id.bunked_num);
        colorText= itemView.findViewById(R.id.color);
        delete= itemView.findViewById(R.id.delete);
        delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mlistener.deleteOnClick(v,getAdapterPosition());
            }
        });
    }
}
public interface butttonsAdapetrListener{
    void deleteOnClick(RecyclerView.ViewHolder v,long position);
}
public void swapCursor(Cursor newCursor){
    if(mCursor!=null){
        mCursor.close();
    }
    mCursor=newCursor;
    if(newCursor!=null){
        notifyDataSetChanged();
    }
}

}

This is my main activity code to delete record from database

public class MainActivity extends AppCompatActivity {
private SQLiteDatabase db;
private CardAdapter mAdapter;
private long id;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    SQLiteOpenHelper proBunkerDatabaseHelper = new ProBunkerDatabaseHelper(this);
    db = proBunkerDatabaseHelper.getWritableDatabase();
    RecyclerView recyclerView =  findViewById(R.id.rv);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    mAdapter = new CardAdapter(this, getCursor(), new CardAdapter.butttonsAdapetrListener() {
        @Override
        public void deleteOnClick(RecyclerView.ViewHolder v, long position) {
            id = (long)v.itemView.getTag();
            db.delete("MYTABLE","_id="+id,null);
            mAdapter.swapCursor(getCursor());
        }
    });
    recyclerView.setAdapter(mAdapter);
    FloatingActionButton b = findViewById(R.id.fab);
    b.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(MainActivity.this,AddSubject.class);
            startActivity(intent);
        }
    });

}
public Cursor getCursor(){
    return db.query("MYTABLE",null,null,null,null,null,"_id ASC");
}

}

The main problem is the when I click on the delete button in any item it is deleting the item which is last in the cursor. there are no compilation errors and runtime issues only the records are not deleting in correct order.

Upvotes: 1

Views: 46

Answers (2)

Jack-Jose Helou
Jack-Jose Helou

Reputation: 1

Another alternative If you want your activity to be clean and not handle data from within. Keep it for the adapter to handle the data being deleted and notifying any change. Just create a listener for the button in the onbindviewholder method.

Upvotes: 0

prashant17
prashant17

Reputation: 1550

Try it like this:

Your interface:

   public interface butttonsAdapetrListener{
    void deleteOnClick(int id,long adapterPos);
   }

Inside your CardViewHolder:

 delete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
        int id = (int)view.getTag();
            mlistener.deleteOnClick(id,getAdapterPosition());
        }
    });

In onBindViewHolder

holder.delete.setTag(id);

In MainActivity onCreate

     mAdapter = new CardAdapter(this, getCursor(), new CardAdapter.butttonsAdapetrListener() {
    @Override
    public void deleteOnClick(int id, long position) {

        db.delete("MYTABLE","_id="+id,null);
        mAdapter.swapCursor(getCursor());
    }
});

Upvotes: 1

Related Questions