Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ItemsRepeater and ScrollView jumping back and forth #9308

Open
christosk92 opened this issue Jan 28, 2024 · 8 comments
Open

ItemsRepeater and ScrollView jumping back and forth #9308

christosk92 opened this issue Jan 28, 2024 · 8 comments
Labels
area-ItemsRepeater area-Scrolling bug Something isn't working team-Controls Issue for the Controls team

Comments

@christosk92
Copy link

christosk92 commented Jan 28, 2024

Describe the bug

This has been an issue for as long as I can remember, I always thought it would be fixed one way or another but now I decided to report a bug on it.

I have a nested ItemsRepeater with the following layout:

   <ItemsRepeater ItemsSource="{x:Bind Discography, Mode=OneWay}">
       <ItemsRepeater.Layout>
           <StackLayout Orientation="Vertical" Spacing="8" />
       </ItemsRepeater.Layout>
       <ItemsRepeater.ItemTemplate>
           <DataTemplate x:DataType="artist:WaveeArtistDiscographyGroupViewModel">
               <Grid>
                   <Grid.RowDefinitions>
                       <RowDefinition Height="Auto" />
                       <RowDefinition />
                   </Grid.RowDefinitions>

                   <TextBlock
                       FontSize="16"
                       FontWeight="SemiBold"
                       Text="{x:Bind Name}" />

                   <ItemsRepeater
                       Grid.Row="1"
                       ItemsSource="{x:Bind Items}" />
               </Grid>
           </DataTemplate>
       </ItemsRepeater.ItemTemplate>
   </ItemsRepeater>

Surrounded with a ScrollView (not ScrollViewer !). Scrolling is fine and smooth (this has been improved over time !) until the end where the scroller glitches and you can see this jumping back and forth effect. (Video below)

Steps to reproduce the bug

  1. Create a nested ItemsRepeater layout with a lot of times.
  2. Surround with ScrollView.
  3. Scroll to end and observe the bug

Expected behavior

No buggy scrolling !

Screenshots

2024-01-29.04-28-34.mp4

NuGet package version

Windows App SDK 1.5 Experimental 2: 1.5.240124002-experimental2

Packaging type

Packaged (MSIX)

Windows version

Windows 10 version 22H2 (19045, 2022 Update)

IDE

Visual Studio 2022-preview

Additional context

No response

@christosk92
Copy link
Author

PS: The issue does not occur when scrolling with the scrollwheel.

@bpulliam bpulliam transferred this issue from microsoft/WindowsAppSDK Feb 1, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Feb 1, 2024
Copy link

github-actions bot commented Feb 1, 2024

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one. Thank you!

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

@bpulliam bpulliam added area-ItemsRepeater area-Scrolling team-Controls Issue for the Controls team and removed needs-triage Issue needs to be triaged by the area owners labels Feb 1, 2024
@duncanmacmichael duncanmacmichael added the bug Something isn't working label Feb 6, 2024
@ranjeshj
Copy link
Contributor

@christosk92 the outer repeater does not know the extent. It is making estimates on what it could be depending on the size of the groups it has seen so far and the number of groups. If the groups are of widely varying sizes, then it is likely that once you scroll to what it thinks is the end, there are more items, its size estimate changes and now the list is bigger than before. This seems to keep repeating. Without knowing the size of all the groups (which is what the outer repeater is trying to do), this is hard to solve. If all the groups are the same size, I suspect it works better. This does make for a weird experience when dragging the mouse thumb.

@christosk92
Copy link
Author

@christosk92 the outer repeater does not know the extent. It is making estimates on what it could be depending on the size of the groups it has seen so far and the number of groups. If the groups are of widely varying sizes, then it is likely that once you scroll to what it thinks is the end, there are more items, its size estimate changes and now the list is bigger than before. This seems to keep repeating. Without knowing the size of all the groups (which is what the outer repeater is trying to do), this is hard to solve. If all the groups are the same size, I suspect it works better. This does make for a weird experience when dragging the mouse thumb.

That makes a lot of sense, thanks for the clarification.

For my case: An album can have a random number of tracks (1, 5,10,12,40 etc and anything in between). I can make an estimation on the number of tracks an album will have (Albums usually have 10, singles 2) but the actual number can change once the album is fetched.

Do you have any clue whatsoever as to how I can approach this problem? Do you think writing my own layout can remedy this? Another option could be to fetch all the album first and then calculate the size based on the number of tracks.... But that is slow and would require a blocking action for the user which is less than ideal...

@christosk92
Copy link
Author

Well another thing I could do is just say like:

  1. Albums have est. 10 tracks
  2. Singles have est. 2 tracks

There is some lazy loading where items get fetched only if they are in the viewport for longer than ~300 ms(?).
This way scrolling never results in unexpected size shifts since the height is already pre-computed.
Thoughts on this?

@ranjeshj
Copy link
Contributor

@christosk92 These are the challenges with virtualized layouts that operate with not enough information. If you can get accurate sizes based on the count of items, writing a custom layout outer layout will definitely get you a better experience. It should be possible to measure each child that is in the viewport and use the counts/sizes to accurately represent the items outside the viewport. As long as the numbers you come up with don't change as you scroll, you should get accurate thumb behavior.

@yaira2
Copy link
Contributor

yaira2 commented May 21, 2024

A user reported this issue in Files as well files-community/Files#15158.

@christosk92
Copy link
Author

@christosk92 These are the challenges with virtualized layouts that operate with not enough information. If you can get accurate sizes based on the count of items, writing a custom layout outer layout will definitely get you a better experience. It should be possible to measure each child that is in the viewport and use the counts/sizes to accurately represent the items outside the viewport. As long as the numbers you come up with don't change as you scroll, you should get accurate thumb behavior.

I get that but with modern data sets (which are probably paged), the result of an API call is unknown, it may be higher or lower than previous items. The scrolling examples in the sample app etc work fine with the most trivial, offline and local datasets that never change. But once you start building real web-connected apps it all changes.

I have never experienced such a thing on mobile apps, or even web apps.
Why isn't this a thing that is being considered? Variable datasets are highly common in a lot of applications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-ItemsRepeater area-Scrolling bug Something isn't working team-Controls Issue for the Controls team
Projects
None yet
Development

No branches or pull requests

5 participants