Recyclerview row item selection color change
Simple and Best
Inside Adapter class
int row_index=0;
inside onBindViewHOlder
holder.titleLL.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
row_index=position;
notifyDataSetChanged();
}
});
if (row_index==position) {
holder.title.setTextColor(Color.RED);
} else {
holder.title.setTextColor(Color.BLACK);
}
Change the onBindViewHolder
method of your NavigationDrawerAdapter.java
into this:
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if(position == selected_item) {
holder.title.setTextColor(Color.parseColor("#00aaff"));
holder.imgViewIcon.setBackgroundResource(R.drawable.ic_circle);
} else {
holder.title.setTextColor(Color.parseColor("#00000")); //actually you should set to the normal text color
holder.imgViewIcon.setBackgroundResource(0);
}
NavDrawerItem current = data.get(position);
holder.title.setText(current.getTitle());
holder.imgViewIcon.setImageResource(current.getIcon());
}
most of the answers for such a question, are about to Override Onclick in onBindViewHolder or implementing an interface for clicking in recycler view. but as we all know, onBindViewHolder is called as your views are populated during scrolling. Thus, you will have numerous calls to setOnClickListener so it is not an efficient way and also implementing interface is not as easy as the answer I got.
here is how you can access selecting items in recycler view and change its background or do what ever you want when an item is selected .
in your ViewHolder constructor use setOnTouchListener for itemView (the argument of constructor) in this way
itemView.setOnTouchListener((v, event) -> {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (v.getTag() == null) {
v.setTag(true);
v.setBackgroundColor(Color.parseColor("#F31807"));
}
else {
v.setBackgroundColor(Color.TRANSPARENT);
v.setTag(null);
}
}
if (event.getAction() == MotionEvent.ACTION_MOVE) {
//default color
v.setBackgroundColor(Color.TRANSPARENT);
}
return true;
});
We use ACTION_UP for check if user pressed the item and after that we save a boolean in view's flag so that we can press every items how many times we want and see the color is changing. ACTION_MOVE if block is for prevent selecting items when scrolling the recycler view. if you see that selecting one item is affecting another items selection, you can use this answer:
issue : RecyclerView messed up data when scrolling
in the end if you are curious about why we return true in method see this video to understand.
tutorial on OnTouchListener And Motionevent
You can use class for Recycler view TouchListener
class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{
private ClickListener clicklistener;
private GestureDetector gestureDetector;
public RecyclerTouchListener(Context context, final RecyclerView recycleView, final ClickListener clicklistener){
this.clicklistener=clicklistener;
gestureDetector=new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child=recycleView.findChildViewUnder(e.getX(),e.getY());
if(child!=null && clicklistener!=null){
clicklistener.onLongClick(child,recycleView.getChildAdapterPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child=rv.findChildViewUnder(e.getX(),e.getY());
RecyclerView.ViewHolder viewHolder=rv.findContainingViewHolder(child);
if(child!=null && clicklistener!=null && gestureDetector.onTouchEvent(e)){
clicklistener.onClick(child,rv.getChildAdapterPosition(child),viewHolder);
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
}
Implement an Interface
public interface ClickListener{
public void onClick(View view, int position,RecyclerView.ViewHolder viewHolder);
public void onLongClick(View view, int position);
}
And in your Main Activity (Here I set Image resource You can set as You like ,Any thing)
Create an arraylist named "selected" as Integer and add following code as OnClickListener
recyclerViewSchedule.addOnItemTouchListener(new RecyclerTouchListener(this,
recyclerViewSchedule, new ClickListener() {
@Override
public void onClick(View view, final int position, RecyclerView.ViewHolder v) {
//Values are passing to activity & to fragment as well
if(!selected.contains(position))
{
selected.add(position);
((ScheduleAdapter.MyHolder) v).txtImage.setBackgroundColor(getResources().getColor(R.color.colorAccent));
}else {
((ScheduleAdapter.MyHolder) v).txtImage.setBackgroundColor(getResources().getColor(R.color.colorTransparent));
selected.remove(new Integer(position));
}
Toast.makeText(ScheduleActivity.this, "Single Click on position :"+position,
Toast.LENGTH_SHORT).show();
}
Toast.makeText(ScheduleActivity.this, "Single Click on position :"+position,
Toast.LENGTH_SHORT).show();
}
@Override
public void onLongClick(View view, int position) {
Toast.makeText(ScheduleActivity.this, "Long press on position :"+position,
Toast.LENGTH_LONG).show();
}
}));
The txtImage I specified here is from RecyclerAdapter,Replace it with Your View
Happy Coding :-)