ImageView not updating in RecyclerView
I have a RecyclerView with the following item layout:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:columnCount="3" android:rowCount="1" android:paddingHorizontal="0dp" android:paddingVertical="2dp" tools:ignore="RequiredSizeWidth,RequiredSizeHeight,MissingInputType,HardcodedText,HardcodedSize,MissingDimension"> <!--paddingLeft = (layout_width - (width of drawable)) / 2-->
<Button android:id="@+id/btnPiece" style="@style/PieceButton" android:layout_column="0" android:drawableLeft="@drawable/meepledrawable" android:paddingLeft="7.5dp" android:drawableTint="@color/RoyalBlue"/>
<EditText android:id="@+id/txtPlayerName" style="@style/PlayerNameEditTextStyle" android:layout_column="1" android:layout_columnWeight="1"/>
<Button android:id="@+id/btnDeletePlayerName" style="@style/BasicDeleteButton" android:layout_column="2" android:layout_marginVertical="0dp" android:layout_marginLeft="0dp" android:layout_marginRight="5dp" android:layout_gravity="center"/>
</GridLayout>
This gives the following in the Visual Studio 2022 Designer:
Notice that the first Button (btnPiece) uses a drawableLeft, not an image. This is done so that I can change the color using drawableTint. In the Adapter, I define OnBindViewHolder as follows:
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
PlayerNameViewHolder vh = holder as PlayerNameViewHolder;
vh.txtPlayerName.Text = this.Players[position].Name;
vh.btnDeletePlayerName.Visibility = position == (this.ItemCount - 1) ? ViewStates.Invisible : ViewStates.Visible;
vh.btnPiece.Visibility = position == (this.ItemCount - 1) ? ViewStates.Invisible : ViewStates.Visible;
if (position < (this.ItemCount - 1))
{
vh.btnPiece.SetCompoundDrawables(this.GetPieceDrawable, null, null, null);
//vh.btnPiece.SetPadding((int)(((vh.btnPiece.Width - 40) / 2) * vh.btnPiece.Context.Resources.DisplayMetrics.Density), 0, 0, 0);
vh.btnPiece.BackgroundTintList = ColorStateList.ValueOf(this.Players[position].PlayerColor);
}
vh.btnPiece.Click += btnPiece_Click;
vh.txtPlayerName.TextChanged += this.txtPlayerName_TextChanged;
vh.txtPlayerName.FocusChange += this.txtPlayerName_FocusChange;
vh.btnDeletePlayerName.Click += this.btnDeletePlayerName_Click;
}
I also define the TextChanged EventHandler as follows:
private void txtPlayerName_TextChanged(object sender, TextChangedEventArgs e)
{
GridLayout grdRoot = (sender as EditText).Parent as GridLayout;
RecyclerView rvPlayerNames = grdRoot.Parent as RecyclerView;
int index = rvPlayerNames.GetChildAdapterPosition(grdRoot);
PlayerNameViewHolder vh = rvPlayerNames.FindViewHolderForAdapterPosition(index) as PlayerNameViewHolder;
if (index != -1)
{
if (index == (this.Players.Count - 1) && this.Players[this.Players.Count - 1].Name.Trim().Length == 0 && e.Text.ToString().Trim().Length > 0)
{
//A new name is being added
this.Players.Add(new PlayerData());
vh.btnPiece.Visibility = ViewStates.Visible;
vh.btnPiece.SetCompoundDrawables(Application.Context.GetDrawable(Resource.Drawable.meepledrawable), null, null, null);
//vh.btnPiece.SetPadding((int)(((vh.btnPiece.Width - 40) / 2) * vh.btnPiece.Context.Resources.DisplayMetrics.Density), 0, 0, 0);
vh.btnPiece.BackgroundTintList = ColorStateList.ValueOf(this.Players[index].PlayerColor);
vh.btnDeletePlayerName.Visibility = ViewStates.Visible;
this.NotifyItemInserted(index + 1);
rvPlayerNames.SmoothScrollToPosition(index);
}
else if (index == (this.Players.Count - 2) && this.Players[this.Players.Count - 2].Name.Length > 0 && e.Text.ToString().Trim().Length == 0)
{
//The last name (2nd last item) is deleted
this.Players.RemoveAt(index + 1);
vh.btnPiece.Visibility = ViewStates.Invisible;
vh.btnDeletePlayerName.Visibility = ViewStates.Invisible;
this.NotifyItemRemoved(index + 1);
}
this.Players[index].Name = e.Text.ToString();
}
}
My goal is to have another item added to the RecyclerView when the EditText (txtPlayerName) has text added to it, as well as unhide the Buttons (btnPiece & btnDeletePlayerName). I also wish to modify the drawableLeft, paddingLeft & drawableTint of the first Button (btnPiece). This all works fine for the EditText (txtPlayerName) & second Button (btnDeletePlayerName), but if I attempt to set the drawableLeft of the first Button (btnPiece) using SetCompoundDrawables (as shown in the code above), it is hidden. Setting only the drawableTint (using BackgroundTintList as shown above) it is still visible, but the color does not change. Setting the paddingLeft (using SetPadding as shown above), however, does work. I'm sure that all of this can somehow be solved using the Notify methods (such as NotifyItemInserted & NotifyItemChanged), but I can't seem to get it to work. Can someone please help? Thanks!