New items are added to RecyclerView each time when Adapter have created. In photo I showed a process where darken dish images appear, though I managed image darking with a condition
if(holder.mDish.getPicurl()!=null)
, but it doest work.
If I go into darken dish image details and go back to list, there will by three darken images. Is it problem with RecyclerView or it is my fault?
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mDish = DISHES.get(position);
final int id = holder.mDish.getId();
if(holder.mDish.getPicurl()!=null) {
Picasso.with(mContext)
.load(holder.mDish.getPicurl())
.fit()
.transform(new RoundedTransformation(20, 0))
.into(holder.mIvBackground);
holder.mIvBackground.setColorFilter(Color.parseColor("#aaaaaa"), PorterDuff.Mode.MULTIPLY);
} else {
holder.mIvBackground.setImageResource(R.drawable.vector_drawable_dish);
}
holder.mTvName.setText(holder.mDish.getName());
//holder.mTvDescription.setText(holder.mDish.getDescription());
holder.mTvPrice.setText("T " + String.valueOf(holder.mDish.getPrice()));
holder.mBtnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(mListener!=null){
mListener.onAddToBasketInteraction(id);
}
}
});
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mListener.onStartDetailActivity(id);
}
});
}
public void addDishes(List<Dish> dishes){
DISHES.clear();
DISHES.addAll(dishes);
notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public Dish mDish;
public final View mView;
public final ImageView mIvBackground;
public final TextView mTvName;
//public final TextView mTvDescription;
public final TextView mTvPrice;
public final ImageButton mBtnAdd;
public ViewHolder(View itemView) {
super(itemView);
mView = itemView;
mIvBackground = (ImageView) itemView.findViewById(R.id.dishBackground);
mTvName = (TextView) itemView.findViewById(R.id.name);
//mTvDescription = (TextView) itemView.findViewById(R.id.description);
mTvPrice = (TextView) itemView.findViewById(R.id.price);
mBtnAdd = (ImageButton) itemView.findViewById(R.id.btnAdd);
}
}
xml of item:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="90dp"
android:orientation="horizontal"
android:padding="2dp">
<ImageView
android:id="@+id/dishBackground"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Плов узбекский"
android:textColor="@color/colorAccent2"
android:layout_marginLeft="5dp"
android:layout_marginBottom="5dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:textSize="14sp" />
<TextView
android:id="@+id/price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="T 3000"
android:textColor="@android:color/holo_orange_light" />
<ImageButton
android:id="@+id/btnAdd"
android:layout_width="30dp"
--------------------------------------------------------------------------------------------------------------------------
1 Answer
You don't undo view changes in conditional statement
The culprit is this piece of code:
if(holder.mDish.getPicurl()!=null) {
Picasso.with(mContext)
.load(holder.mDish.getPicurl())
.fit()
.transform(new RoundedTransformation(20, 0))
.into(holder.mIvBackground);
holder.mIvBackground.setColorFilter(Color.parseColor("#aaaaaa"), PorterDuff.Mode.MULTIPLY);
} else {
holder.mIvBackground.setImageResource(R.drawable.vector_drawable_dish);
}
The way
RecyclerView
works is it reuses the same views with a different data (hence recycler), so the onBindViewHolder
method may be called multiple times for each position, but the ViewHolder
might have been already created and previously bound to a different piece of data. That way some changes applied to the view inside the onBindViewHolder
method might persist through bind calls to different pieces of data.
In your case, the following call:
holder.mIvBackground.setColorFilter(Color.parseColor("#aaaaaa"), PorterDuff.Mode.MULTIPLY);
alters the view with the color filter within one call to
onBindViewHolder
. Then, when another piece of data is bound to the same ViewHolder
, the condition holder.mDish.getPicurl()!=null
might be false, but the effect still persists, because there is no removal of this color filter in the else
branch of your statement.Fix
You need to explicitly set and unset any changes to a single view in your
RecyclerView
for every separate condition you wish to implement:if(holder.mDish.getPicurl()!=null) {
holder.mIvBackground.setColorFilter(Color.parseColor("#aaaaaa"), PorterDuff.Mode.MULTIPLY);
} else {
holder.mIvBackground.setColorFilter(null); // removes color filter
}
You don't see any problems with your
mIvBackground
because you set a different one in each branch of your if-else statement, so no unwanted state persists.
No comments:
Post a Comment