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 Button
s (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!