I have been exploring Recyclerview and Cardview and I stumbled across this one problem in which I don't know how to handle it. My recyclerview works fine but when I make the recyclerview's item background change color on click, it behaves weirdly.
Ok so, the recyclerview loads normally however when I first click on an item, the item background color flickers its new color but then stays in its default color. When I click on any item for the second time, only then the recyclerview's item change its background coloras it supposed to along with the rest of the item clicked.
From the Log.d
that I've added to my code, I found that what differ first click with the second(and the rest) click is the public PremiseAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
in the class PremiseAdapter
. I found a question similar my problem but I don't think my code works that way.
The logs are as below.
.... D/rcvTest: PremiseAdapter.PremiseAdapter
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: ---------------------> PremiseAdapter.ViewHolder.onCreateViewHolder
.... D/rcvTest: [ViewHolder].ViewHolder.TOP
.... D/rcvTest: PremiseAdapter.onBindViewHolder
.... D/rcvTest: [ViewHolder].bindTo.TOP: FroyYo Mart
.... D/rcvTest: [ViewHolder].bindTo.BOTTOM FroyYo Mart
.... D/rcvTest: PremiseAdapter.onBindViewHolder.get(position)
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: ---------------------> PremiseAdapter.ViewHolder.onCreateViewHolder
.... D/rcvTest: [ViewHolder].ViewHolder.TOP
.... D/rcvTest: PremiseAdapter.onBindViewHolder
.... D/rcvTest: [ViewHolder].bindTo.TOP: Ice Cream Store
.... D/rcvTest: [ViewHolder].bindTo.BOTTOM Ice Cream Store
.... D/rcvTest: PremiseAdapter.onBindViewHolder.get(position)
.... D/rcvTest: [ViewHolder].ViewHolder.listener: null
.... D/rcvTest: [ViewHolder].ViewHolder.getAdapterPosition(): 1
.... D/rcvTest: [ViewHolder].ViewHolder.position: 1
.... D/rcvTest: getLayoutPosition(): 1
.... D/rcvTest: [ViewHolder].ViewHolder.position != RecyclerView.NO_POSITION
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: ---------------------> PremiseAdapter.ViewHolder.onCreateViewHolder
.... D/rcvTest: [ViewHolder].ViewHolder.TOP
.... D/rcvTest: PremiseAdapter.onBindViewHolder
.... D/rcvTest: [ViewHolder].bindTo.TOP: Ice Cream Store
.... D/rcvTest: [ViewHolder].bindTo.BOTTOM Ice Cream Store
.... D/rcvTest: PremiseAdapter.onBindViewHolder.get(position)
.... D/rcvTest: [ViewHolder].ViewHolder.listener: null
.... D/rcvTest: [ViewHolder].ViewHolder.getAdapterPosition(): 0
.... D/rcvTest: [ViewHolder].ViewHolder.position: 0
.... D/rcvTest: getLayoutPosition(): 0
.... D/rcvTest: [ViewHolder].ViewHolder.position != RecyclerView.NO_POSITION
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: PremiseAdapter.onBindViewHolder
.... D/rcvTest: [ViewHolder].bindTo.TOP: FroyYo Mart
.... D/rcvTest: [ViewHolder].bindTo.BOTTOM FroyYo Mart
.... D/rcvTest: PremiseAdapter.onBindViewHolder.get(position)
.... D/rcvTest: PremiseAdapter.getItemCount
And this is my PremiseAdapter.java
file which contains my PremiseAdapter
class and ViewHolder
class.
public class PremiseAdapter extends RecyclerView.Adapter<PremiseAdapter.ViewHolder> {
private ArrayList<Premise> mPremiseData;
private Context context;
private int selected_position = -1;
OnItemClickListener onItemClickListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener itemClickListener) {
onItemClickListener = itemClickListener;
}
public PremiseAdapter(Context context, ArrayList<Premise> mPremiseData) {
Log.d("rcvTest", "PremiseAdapter.PremiseAdapter");
this.mPremiseData = mPremiseData;
this.context = context;
}
//Required method for creating the viewholder objects.
@NonNull
@Override
public PremiseAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.d("rcvTest", "---------------------> PremiseAdapter.ViewHolder.onCreateViewHolder");
return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_premises, parent, false), onItemClickListener);
}
//Required method that binds the data to the viewholder.
@Override
public void onBindViewHolder(@NonNull PremiseAdapter.ViewHolder holder, int position) {
// Get current premise.
// Populate the textviews with data.
}
@Override
public int getItemCount() {
Log.d("rcvTest", "PremiseAdapter.getItemCount");
return mPremiseData.size();
}
/*----------------------------------- CLASS VIEWHOLDER -------------------------------------------*/
/*----------------------------------- CLASS VIEWHOLDER -------------------------------------------*/
/*class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {*/
class ViewHolder extends RecyclerView.ViewHolder {
// Member Variables for the TextViews
//Constructor for the ViewHolder, used in onCreateViewHolder().
ViewHolder(@NonNull View itemView, OnItemClickListener listener) {
super(itemView);
cardView = itemView.findViewById(R.id.cardview_premise);
Log.d("rcvTest", "[ViewHolder].ViewHolder.TOP");
// Initialize the views.
// Set the OnClickListener to the entire view.
int clickedColor = Color.parseColor("#D5F5E3");
itemView.setOnClickListener((v) -> {
int position = getAdapterPosition();
Log.d("rcvTest", "[ViewHolder].ViewHolder.listener: " + listener);
Log.d("rcvTest", "[ViewHolder].ViewHolder.getAdapterPosition(): " + getAdapterPosition());
Log.d("rcvTest", "[ViewHolder].ViewHolder.position: " + position);
Log.d("rcvTest", "getLayoutPosition(): " + getLayoutPosition());
if (position != RecyclerView.NO_POSITION) {
Log.d("rcvTest", "[ViewHolder].ViewHolder.position != RecyclerView.NO_POSITION");
itemView.setBackgroundColor(clickedColor);
} else if (position == RecyclerView.NO_POSITION) {
Log.d("rcvTest", "[ViewHolder].ViewHolder.position == RecyclerView.NO_POSITION");
itemView.setBackgroundColor(clickedColor);
}
notifyItemChanged(position);
notifyItemChanged(getLayoutPosition());
});
}
void bindTo(Premise currentPremise) {
// Populate the textviews with data.
Log.d("rcvTest", "[ViewHolder].bindTo.TOP: " + currentPremise.getPremiseName());
}
}
}
Try this out. Recently I have code this and its working fine, hope so it will solve your problem too.
int row_index = -1;
holder.itemView.setOnClickListener(v -> {
row_index = position;
notifyDataSetChanged();
});
if (row_index == position) {
holder.layout.setBackgroundColor(Color.parseColor("#ff6600"));
} else {
holder.layout.setBackgroundColor(Color.parseColor("#ffffff"));
}