danmacleod
Newbie
I have a RecyclerView to display a list of items. When I click on an item, the item will display an image, when I click on the item again, the image will be 'hidden'. This is working for the item I click on. However, when I click on an item to display the image, another item further down the list also gets it's image displayed which is not what I want. For example, if I have a list of 15 items and I click on item 1, it's image will be updated, but item 11 will also get its image updated. I put breakpoints in the onClick method but it only gets called once for the correct item so I'm not sure how the other item is getting updated. Any ideas?
ADAPTER CONFIGURATION
ADAPTER AND VIEWHOLDER
ITEM LAYOUT
ADAPTER CONFIGURATION
Code:
mDataSet = getSavedChecklists();
toDelete = new boolean[ mDataSet.size() ];
ChecklistDeleteAdapter mListAdapter = new ChecklistDeleteAdapter( getContext(), mDataSet, R.layout.item_checklist, toDelete, mDeleteBtn );
mRecyclerView.setAdapter( mListAdapter );
ADAPTER AND VIEWHOLDER
Code:
public class ChecklistDeleteAdapter extends RecyclerView.Adapter<ChecklistDeleteAdapter.ViewHolder> {
/** Store a member variable for the list. */
private List<Checklist> mDataSet;
/** Context reference. */
private Context mContext;
/** Keeps track of what items will be deleted. */
private boolean[] mToDelete;
/** Screen's delete button. */
private Button mDeleteBtn;
/** Layout Id. */
private int mLayoutId;
/**************************************************************************
* @param context Context
* @param items List<Checklist>
**************************************************************************/
public ChecklistDeleteAdapter( Context context, List<Checklist> items, int layoutId, boolean[] toDelete, Button deleteBtn ) {
mDataSet = items;
mContext = context;
mToDelete = toDelete;
mDeleteBtn = deleteBtn;
mLayoutId = layoutId;
}
/**************************************************************************
* Called when RecyclerView needs a new RecyclerView.ViewHolder of the
* given type to represent an item.
* @param parent ViewGroup
* @param viewType int
* @return ChecklistDeleteAdapter.ViewHolder
**************************************************************************/
@NonNull
@Override
public ChecklistDeleteAdapter.ViewHolder onCreateViewHolder( @NonNull ViewGroup parent, int viewType ) {
View view = LayoutInflater.from( parent.getContext() ).inflate( mLayoutId, parent, false );
return new ViewHolder( view );
}
/**************************************************************************
* Called by RecyclerView to display the data at the specified position.
* Populates data into the item through the holder.
* @param viewHolder ChecklistDeleteAdapter.ViewHolder
* @param position int
**************************************************************************/
@Override
public void onBindViewHolder( @NonNull final ChecklistDeleteAdapter.ViewHolder viewHolder, int position ) {
Checklist list = mDataSet.get( position );
viewHolder.name.setText( list.getName() );
}
/**************************************************************************
* Updates delete button text with number of Checklists to delete.
**************************************************************************/
private void updateBtnTxt() {
int selected = 0;
for ( final boolean toggled : mToDelete ) {
if ( toggled ) {
selected += 1;
}
}
if ( selected == 0 ) {
mDeleteBtn.setText( mContext.getResources().getString( R.string.delete ) );
} else {
mDeleteBtn.setText( String.format( mContext.getResources().getString( R.string.sub_delete ), selected ) );
}
}
/**************************************************************************
* Returns the total number of items in the data set held by the adapter.
* @return int the item count
**************************************************************************/
@Override
public int getItemCount() {
return mDataSet.size();
}
/**************************************************************************
* Provides a direct reference to each of the views within a data item.
* Used to cache the views within the item layout for fast access
**************************************************************************/
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView name;
public ImageView delImage;
private ItemClickListener itemClickListener;
/**********************************************************************
* A constructor that accepts the entire item row and does the view
* lookups to find each subview.
* @param itemView View
**********************************************************************/
private ViewHolder( View itemView ) {
super( itemView );
name = itemView.findViewById( R.id.text );
delImage = itemView.findViewById( R.id.right_image );
itemView.setOnClickListener( this );
}
private void setItemClickListener( ItemClickListener itemClickListener ) {
this.itemClickListener = itemClickListener;
}
@Override
public void onClick( View view ) {
int position = getAdapterPosition();
if ( mToDelete[ position ] ) {
delImage.setImageResource( R.drawable.filler );
Log.v("sb", "Filler " + position);
} else {
delImage.setImageResource( R.drawable.ic_clear );
Log.v("sb", "X-image " + position);
}
// toggle values
mToDelete[ position ] = !mToDelete[ position ];
updateBtnTxt();
}
}
}
ITEM LAYOUT
Code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Used to display items in a list. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_layout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<ImageView
android:id="@+id/left_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="8dp"
android:contentDescription="@string/empty_image"/>
<TextView
android:id="@+id/text"
style="@style/Lists"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="7dp"
/>
<ImageView
android:id="@+id/right_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="16dp"
android:contentDescription="@string/empty_image" />
</LinearLayout>