question

njsokalski avatar image
0 Votes"
njsokalski asked RobCaplan edited

Inconsistent Displaying of TextView in RecyclerView

I have a RecyclerView that contains a list of integers for which I want to calculate and set the width. Here is the method I use to do this:

 private void UpdateRoundNumbers()
 {
     (this.rvRoundNumbers.GetAdapter() as RoundNumbersAdapter).RoundNumbers.Add(this.rvRoundNumbers.GetAdapter().ItemCount + 1);
     this.rvRoundNumbers.GetAdapter().NotifyItemInserted(this.rvRoundNumbers.GetAdapter().ItemCount - 1);
    
     TextView tv = new TextView(Application.Context, null, 0, Resource.Style.ItemTextView);
     this.rvRoundNumbers.LayoutParameters.Width = (int)Enumerable.Range(1, ScorePadApplication.Players.Max((pd) => pd.Scores.Count) + 1).Max((roundnumber) => { return tv.Paint.MeasureText(roundnumber.ToString()); }) + tv.PaddingStart + tv.PaddingEnd;
 }

However, the RecyclerView (the black column on the left in the screenshots) is not always displaying the added values, even though I call NotifyItemInserted. I have confirmed that the value calculated by the method is correct even when it does not display the new values, and when one value is not displayed, that continues for the rest of the debugging session. Here are screenshots of when it works & doesn't work:

106384-screenshot-1623899943.png

106385-screenshot-1623899982.png

I change no code between debug sessions, and yet it still happens inconsistently (the two screenshots were taken back to back by doing nothing other than starting a new debug session). What could be causing something like this? Thanks.


dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

JarvanZhang-MSFT avatar image
0 Votes"
JarvanZhang-MSFT answered JarvanZhang-MSFT commented

Hello,​

Welcome to our Microsoft Q&A platform!

It seems there is nothing wrong with the code that adding the new values for the recyclerView. The problem may be related to the rendering view. If you want to set adaptive width the recyclerView, you could just set the width of the recyclerView to wrap_content. Then it will adjust it's width automatically when adding new items..

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/test_recyclerView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

Best Regards,

Jarvan Zhang


If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Using wrap_content is actually what I tried to do when I first designed the app. However, because not all values for the RecyclerView are always visible, wrap_content would sometimes cause the width to change during scrolling (due to the wider items becoming visible/hidden). I need the RecyclerView to be the width of the widest item, even if that item is not currently visible.

0 Votes 0 ·

wrap_content would sometimes cause the width to change during scrolling (due to the wider items becoming visible/hidden)

To avoid this, it's suggested to set a fixed value to the width of recyclerView. The width will only change when the data's count reaches one stage, for example, 10 items, 100 items. You could detect the list's count to choose the corresponding value and set for the recyclerView.

var number = Math.Ceiling(Math.Log10(data.Count + 1));
switch (number)
{
    case 1:
        recyclerView.LayoutParameters.Width = 40;
        break;
    case 2:
        recyclerView.LayoutParameters.Width = 80;
        break;
    case 3:
        recyclerView.LayoutParameters.Width = 120;
        break;
    default:
        break;
}

If you want to add the items dynamically, please detect the CollectionChanged event and call the above code in it.

0 Votes 0 ·