Reputation: 155
Im trying to make a selected item in the RecyclerView to change it's background when it is clicked, but once the other item in the RecyclerView is clicked, that item's background will be changed and the previously clicked item will change back to original.
I only manage to make the item change back to orignal(white background) when it is clicked the second time.
Any help please?
This is my RecyclerView Adapter
public class CharityListAdapter extends RecyclerView.Adapter<CharityListAdapter.CharityListViewHolder> {
String charityData[], descriptionData[];
int images[];
Context context;
public CharityListAdapter(Context ct, String charity[], String description[], int image[]) {
context = ct;
charityData = charity;
descriptionData= description;
images = image;
}
@NonNull
@Override
public CharityListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.data_row, parent, false);
return new CharityListViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final CharityListViewHolder holder,final int position) {
holder.titleText.setText(charityData[position]);
holder.descText.setText(descriptionData[position]);
holder.charityImage.setImageResource(images[position]);
holder.charityLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(holder.charityLayout.isSelected()) {
holder.charityLayout.setSelected(false);
System.out.println("Set to false");
} else if(!holder.charityLayout.isSelected()){
holder.charityLayout.setSelected(true);
System.out.println("Set to true");
}
if(holder.charityLayout.isSelected()) {
holder.whiteBox.setBackgroundResource(R.drawable.bluebox);
DonateSelection.enableNextButton();
System.out.println("Blue Box");
}
if(!holder.charityLayout.isSelected()) {
holder.whiteBox.setBackgroundResource(R.drawable.box);
System.out.println("White Box");
}
}
});
}
@Override
public int getItemCount() {
return images.length;
}
public class CharityListViewHolder extends RecyclerView.ViewHolder {
TextView titleText, descText;
ImageView charityImage;
RelativeLayout whiteBox;
RelativeLayout charityLayout;
public CharityListViewHolder(@NonNull View itemView) {
super(itemView);
titleText = itemView.findViewById(R.id.titleText);
descText = itemView.findViewById(R.id.descText);
charityImage = itemView.findViewById(R.id.charityImage);
whiteBox = itemView.findViewById(R.id.whiteBox);
charityLayout = itemView.findViewById(R.id.charityLayout);
}
}
}
Upvotes: 1
Views: 901
Reputation: 833
Rather than remembering the layout/ViewHolder you selected, it's better to remember the selected position. In your adapter add:
private int positionSelected = -1;
-1 indicates none is selected.
And then, in your ViewHolder constructor:
public CharityListViewHolder(@NonNull View itemView) {
super(itemView);
....
charityLayout = itemView.findViewById(R.id.charityLayout);
charityLayour.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
positionSelected = getAdapterPosition();
notifyDataSetChanged();
}
});
}
In your onBindViewHolder you can set the background accordingly:
if (position == positionSelected) {
// Set background for layout to indicate selected
} else {
// Set background for layout to indicate unselected
}
Upvotes: 1
Reputation: 1453
This is because of how RecyclerView works. It recycles your view after it disappears from your screen. You should use if/else to maintain the right state of a view. Replace your onClick action with below code.
holder.charityLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(holder.charityLayout.isSelected()) {
holder.charityLayout.setSelected(false);
System.out.println("Set to false");
} else {
holder.charityLayout.setSelected(true);
System.out.println("Set to true");
}
if(holder.charityLayout.isSelected()) {
holder.whiteBox.setBackgroundResource(R.drawable.bluebox);
DonateSelection.enableNextButton();
System.out.println("Blue Box");
}else{
holder.whiteBox.setBackgroundResource(R.drawable.box);
System.out.println("White Box");
}
}
});
Edited Here is raw code.But, I think that should work. You should add an array of check state that recycler is composed of. By default they all will be false. Then, check it onBindViewHolder(). When click, set boolean to true and call notifyDatasetChanged.
public class CharityListAdapter extends RecyclerView.Adapter<CharityListAdapter.CharityListViewHolder> {
String charityData[], descriptionData[];
int images[]; boolean checkState[];
Context context;
public CharityListAdapter(Context ct, String charity[], String description[], int image[],boolean checkState[]) {
context = ct;
charityData = charity;
descriptionData= description;
images = image;
checkState=checkState;
}
@NonNull
@Override
public CharityListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.data_row, parent, false);
return new CharityListViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final CharityListViewHolder holder,final int position) {
holder.titleText.setText(charityData[position]);
holder.descText.setText(descriptionData[position]);
holder.charityImage.setImageResource(images[position]);
if(checkState[position]){
holder.whiteBox.setBackgroundResource(R.drawable.bluebox);
DonateSelection.enableNextButton();
}else{
holder.whiteBox.setBackgroundResource(R.drawable.box);
}
holder.charityLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(checkState[position]){
checkState[position]=false;
}else{
checkState[position]=true;
}
notifyDataSetChanged();
}
});
}
@Override
public int getItemCount() {
return images.length;
}
public class CharityListViewHolder extends RecyclerView.ViewHolder {
TextView titleText, descText;
ImageView charityImage;
RelativeLayout whiteBox;
RelativeLayout charityLayout;
public CharityListViewHolder(@NonNull View itemView) {
super(itemView);
titleText = itemView.findViewById(R.id.titleText);
descText = itemView.findViewById(R.id.descText);
charityImage = itemView.findViewById(R.id.charityImage);
whiteBox = itemView.findViewById(R.id.whiteBox);
charityLayout = itemView.findViewById(R.id.charityLayout);
}
}
}
Upvotes: 1