Reputation: 424
I have a recyclerview which shows several(8) cardviews. Inside each cardview, there are several elements like text, imagebutton,etc. Inside the Adapter class (RvAdapter extends RecyclerView.Adapter) I have a code as below. What I want to do is change the color of Vector (.xml) assigned to the imagebutton using the OnClickListener of the same button.
public RvAdapter(Context context,List<Person> persons) {
this.mContext=context;
this.persons=persons;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_content,parent,false);
ViewHolder vh=new ViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final ViewHolder mHolder=holder;
mHolder.personName.setText(persons.get(position).name);
mHolder.personAge.setText(( persons.get(position).age));
mHolder.cvCard.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mContext,"card number:"+String.valueOf(position),Toast.LENGTH_SHORT).show();
}
});
//this is where the error comes
mHolder.alarmImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//this code line doesnt work
//mHolder.alarmImageButton.setColorFilter(R.color.colorAccent);
//this code line works... but it changes the imagebutton color of another card view at below of the recycler view
mHolder.alarmImageButton.setColorFilter(Color.argb(255,255,255,255));
Toast.makeText(mContext,"button:"+String.valueOf(position),Toast.LENGTH_SHORT).show();
}
});
}
RecyclerView has 8 cardviews inside it. When the imagebutton of the first cardview's imagebutton is clicked, it changes the color to white. But the error is it changes the color of 7th card's imagebutton color too. When the second cardview's imagebutton is clicked it changes the 8th card's imagebutton color too. However, the Toast works fine. It shows that click event has identify the position of each cardview and imagebutton properly.
I just couldn't figure this out properly. How the 1st card 7th card views are connected with each other ?
This is my ViewHolder class
public class ViewHolder extends RecyclerView.ViewHolder{
CardView cvCard;
TextView personName;
TextView personAge;
ImageButton alarmImageButton;
public ViewHolder(View itemView) {
super(itemView);
cvCard=(CardView)itemView.findViewById(R.id.cv_card);
personName=(TextView)itemView.findViewById(R.id.txt_person_name);
personAge=(TextView)itemView.findViewById(R.id.txt_person_age);
alarmImageButton=(ImageButton)itemView.findViewById(R.id.alarm_image_button);
}
It will be a great help if someone can help me to find this error...
Upvotes: 1
Views: 307
Reputation: 19427
I just couldn't figure this out properly. How the 1st card 7th card views are connected with each other?
The point of using a RecyclerView
is that the View
s are getting recycled.
You set the colorFilter of the ImageButton
, but that same button may be used in a recycled View
also.
You should store the clicked state of your RecyclerView
rows and set the colorFilter accordingly on each ImageButton
in onBindViewHolder()
.
For example:
// a HashSet to store the clicked positions
private HashSet<Integer> clickedPositions = new HashSet<>();
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final ViewHolder mHolder = holder;
mHolder.personName.setText(persons.get(position).name);
mHolder.personAge.setText((persons.get(position).age));
mHolder.cvCard.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mContext, "card number:" + String.valueOf(position),
Toast.LENGTH_SHORT).show();
}
});
if (clickedPositions.contains(mHolder.getAdapterPosition())) {
// the current item is clicked, change its color
mHolder.alarmImageButton.setColorFilter(Color.argb(255, 255, 255, 255));
} else {
// else change it to another color
mHolder.alarmImageButton.setColorFilter(Color.argb(0, 0, 0, 0));
}
mHolder.alarmImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mContext, "button:" + String.valueOf(position),
Toast.LENGTH_SHORT).show();
// if the item is already clicked, remove it from the clicked items
if (!clickedPositions.remove(mHolder.getAdapterPosition())) {
// if not clicked, add it to the clicked items
clickedPositions.add(mHolder.getAdapterPosition());
}
// and notify the Adapter that the item is changed
notifyItemChanged(mHolder.getAdapterPosition());
}
});
}
Upvotes: 2
Reputation: 1
Store the ids in a sparsebooleanarray. if the colour is changed store true otherwise false.
add these methods to your adapter.
private SparseBooleanArray mSelectedItemsIds;
//Methods to do Selection
public void toggleSelection(int position) {
selectView(position, !mSelectedItemsIds.get(position));
}
//Remove selected selections
public void removeSelection() {
mSelectedItemsIds = new SparseBooleanArray();
notifyDataSetChanged();
}
//Put or delete selected position into SparseBooleanArray
public void selectView(int position, boolean value) {
if (value)
mSelectedItemsIds.put(position, value);
else
mSelectedItemsIds.delete(position);
// notifyItemChangedAtPosition(position);
notifyDataSetChanged();
}
then call it as and when required.
Upvotes: 0