unoplatform / uno.extensions

Libraries to ease common developer tasks associated with building multi-platform mobile, desktop and web applications using Uno Platform or WinAppSDK.
https://platform.uno/
Other
75 stars 47 forks source link

ListView do not scrolled after full scrolling to down and up #2609

Open kni opened 1 month ago

kni commented 1 month ago

Current behavior

I can scroll big ListView to down and return to up. Then scrolling do not work! After select element scrolling work to one full scrolling and again hangs.

Expected behavior

No response

How to reproduce it (as minimally and precisely as possible)

// dotnet new unoapp -o Foo -preset blank -markup csharp -platforms windows android -presentation mvux
// Copy this to MainPage.cs file

namespace Foo;

public partial record Person(string FirstName, string LastName);

public interface IPeopleService {
    ValueTask<IImmutableList<Person>> GetPeopleAsync(CancellationToken ct);
}

public class PeopleService : IPeopleService {
    public async ValueTask<IImmutableList<Person>> GetPeopleAsync(CancellationToken ct) {
        await Task.Delay(TimeSpan.FromSeconds(2), ct);

        var people = new Person[] {
            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa"),

            new Person(FirstName: "Master", LastName: "Yoda"),
            new Person(FirstName: "Darth", LastName: "Vader"),
            new Person(FirstName: "Luke", LastName: "Skywalker"),
            new Person(FirstName: "Han", LastName: "Solo"),
            new Person(FirstName: "Leia", LastName: "Organa")
        };

        return people.ToImmutableList();
    }
}

public partial record PeopleModel(IPeopleService PeopleService) {
    public IState<Person> SelectedPerson => State<Person>.Empty(this);
    public IListFeed<Person> People => ListFeed.Async(PeopleService.GetPeopleAsync).Selection(SelectedPerson);
}

public sealed partial class MainPage : Page {
    public MainPage() {
        this.DataContext(new PeopleViewModel(new PeopleService()), (page, vm) => page
            .Background(ThemeResource.Get<Brush>("ApplicationPageBackgroundThemeBrush"))
            .Content(new Grid()
                .RowDefinitions<Grid>("Auto, *, Auto")
                .VerticalAlignment(VerticalAlignment.Center)
                .HorizontalAlignment(HorizontalAlignment.Center)
                .Children(
                    new TextBlock().Grid(row: 0)
                        .Text("Hello Uno Platform!\n\nListView:\n"),
                    new ListView().Grid(row: 1)
                        .ItemsSource(x => x.Binding(() => vm.People))
                        .ItemTemplate<Person>((person) => new TextBlock().Text(() => person, person => $"{person.FirstName} {person.LastName}")),
                    new TextBlock().Grid(row: 2)
                        .Text(() => vm.SelectedPerson, person => $"\nSelected person: {person.FirstName} {person.LastName}\n")
                )
            )
        );
    }
}

Workaround

No response

Works on UWP/WinUI

None

Environment

No response

NuGet package version(s)

No response

Affected platforms

Android

IDE

Visual Studio 2022

IDE version

No response

Relevant plugins

No response

Anything else we need to know?

No response

ramezgerges commented 1 month ago

@kni Can you provide as with a full repro project in a zip? I copied the code from the issue but it's full of build errors.

kni commented 1 month ago

Foo.zip

ramezgerges commented 1 month ago

@kni I can't reproduce on Desktop or Android. I tried the Uno.Sdk version in the zip and also the latest Uno.Sdk.

kni commented 1 month ago

Maybe it depends on the workload?

My dotnet workload list is:

Installed Workload Id Manifest Version Installation Source

android 34.0.143/8.0.100 SDK 8.0.400, VS 17.11.35327.3 ios 18.0.8303/8.0.100 SDK 8.0.400, VS 17.11.35327.3 maccatalyst 18.0.8303/8.0.100 SDK 8.0.400, VS 17.11.35327.3 maui-windows 8.0.82/8.0.100 SDK 8.0.400, VS 17.11.35327.3

To the point. I reproduce also https://github.com/unoplatform/uno/issues/14792

ramezgerges commented 1 month ago

@MartinZikmund Could you try the given repro? Maybe you can get it to reproduce.

kni commented 1 month ago

There is another such error for Windows. If you press the Down key, wait for the end of the list, then the Up Key to the beginning. And do so several times. Then the program crashes.

jeromelaban commented 3 weeks ago

@kni as you mention that it reproduces on android, could you provide the logcat from the device you're running on?

You can do that with the following commands:

> adb logcat -G 64M
> adb logcat -c
rem Start and crash the app here, wait 2-3 seconds and then:
> adb logcat -d > logcat.txt
kni commented 3 weeks ago

But app is crashed only under Windows. On Android, ListView is wokred not correct, but app not crashed. I can record a video.

You can not reproduces? Could it depend on the phone? I have Redmi 12 with Android 14.

jeromelaban commented 3 weeks ago

Thanks. You mentioned Android in the target platforms, hence the question. If the app crashes on windows, can you provide a stacktrace of the crash?

For android, even if it does not crash, please provide the logcat, it may indicate useful information.

kni commented 3 weeks ago

I hope I did what you wanted:

Exception in App.g.i.cs

#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
            UnhandledException += (sender, e) =>
            {
                if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
            };
#endif
e.Exception.StackTrace   
   at ABI.System.Collections.Generic.IReadOnlyList`1.ToAbiHelper.EnsureIndexInt32(UInt32 index, Int32 limit)
   at ABI.System.Collections.Generic.IReadOnlyList`1.ToAbiHelper.GetAt(UInt32 index)
   at ABI.System.Collections.Generic.IReadOnlyListMethods`2.Do_Abi_GetAt_0(IntPtr thisPtr, UInt32 index, TAbi* __return_value__)
Exception = {"This collection cannot work with indices larger than Int32.MaxValue - 1 (0x7FFFFFFF - 1). (Parameter 'index')"}

_data = {System.Collections.ListDictionaryInternal}
HResult = -2147483637

I think the reason of this error is the same for both Windows and Android: list Virtualising. I watched (on Android) that some elements of list become empty.

jeromelaban commented 2 weeks ago

Thanks. This indeed feels like a bug in virtualization, but it could be related to the ListFeed handling of virtualization.