Xamarin.Forms 在 CollectionView 中实现延迟加载

问题描述

这是我的 CollectionView xaml 文件

    <ContentPage.Content>
        <Grid>
            <StackLayout>
                <RefreshView IsRefreshing="{Binding IsRefreshing,Mode=OneWay}"
             Command="{Binding LoadRefreshCommand}">
                    <CollectionView ItemsSource="{Binding Photos}" SelectedItem="{Binding SelectedPhoto}" RemainingItemsThreshold="10" RemainingItemsThresholdReachedCommand="{Binding LoadNewPhotosCommand}" >
                        <CollectionView.ItemTemplate>
                            <DataTemplate>
                                <Frame BorderColor="#3498DB">
                                    <Grid  RowSpacing="0" ColumnSpacing="0" Padding="0">
                                        <Grid.ColumnDeFinitions>
                                            <ColumnDeFinition Width="*"/>
                                            <ColumnDeFinition Width="3*"/>

                                        </Grid.ColumnDeFinitions>
                                        <Grid.GestureRecognizers>
                                            <TapGestureRecognizer  Command="{Binding Source={x:Reference CurrentPage},Path=BindingContext.LoadPhotosCommand}" />
                                        </Grid.GestureRecognizers>
                                        <Image Aspect="AspectFit" HeightRequest="50" Source="{Binding Url}"  Grid.Column="0"></Image>
                                        <Frame HasShadow="False" VerticalOptions="Center"  Grid.Column="1">
                                            <Label Text="{Binding Title}"></Label>
                                        </Frame>
                                    </Grid>
                                </Frame>
                            </DataTemplate>
                        </CollectionView.ItemTemplate>
                    </CollectionView>
                </RefreshView>
            </StackLayout>
            <StackLayout HorizontalOptions="CenterandExpand" VerticalOptions="Center">
                <Frame IsVisible="{Binding IsBusy}" BorderColor="#3498DB" HasShadow="False" BackgroundColor="#eeeeee">
                    <StackLayout>
                        <ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="{Binding IsBusy}" HorizontalOptions="Center" VerticalOptions="Center"></ActivityIndicator>
                        <Label TextColor="#3498DB" Text="Loading Data,Please Wait..." HorizontalTextAlignment="Center" VerticalTextAlignment="Center" HorizontalOptions="Center" VerticalOptions="Center" IsVisible="{Binding IsBusy}"/>
                    </StackLayout>
                </Frame>
            </StackLayout>
        </Grid>
    </ContentPage.Content>

这是 viewmodel 中的构造函数

        public MainPageviewmodel()
        {
            LoadPhotosCommand = new Command(execute: async () => await ExecuteGetAllPhotos());
            LoadRefreshCommand = new Command(execute: async () => await ExecuteRefreshGetAllPhotos());
            LoadRefreshCommand = new Command(execute: async () => await ExecuteGetNewPhotos());
            Photos = new ObservableCollection<Photo>();
            PhotosModel = new PhotosModel();
            SelectedPhoto = new Photo();
        }

这是 viewmodel 中我如何获取数据的代码

        async Task ExecuteGetAllPhotos()
        {
            if (IsBusy)
                return;      
            try
            {
                IsBusy = true;
                Photos.Clear();
                PhotosModel = await InstagramCloneDataStore.GetAllPhotos();
               if(PhotosModel!=null)
                {
                    foreach (var photo in PhotosModel.Photos)
                    {
                       Photos.Add(photo);                      
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                var msg = ex.Message;
            }
            finally
            {
                IsBusy = false;
            }
        }

当读取 100,200,500 个数据条目时,此代码工作得很好。但是当我读取 5000 个数据条目时,应用程序被冻结并想要强制停止。等待大约 2-3 分钟才能显示数据。所以我想为延迟加载或无限滚动实现一些逻辑。 这是 RemainingItemsThresholdReachedCommand 的命令函数,应该为滚动数据编写逻辑:

        async Task ExecuteGetNewPhotos()
        {
            if (IsBusy)
                return;
            try
            {
//some logic here---------->
                IsBusy = true;
                Photos.Clear();
                PhotosModel = await InstagramCloneDataStore.GetAllPhotos();
                if (PhotosModel != null)
                {
                    foreach (var photo in PhotosModel.Photos)
                    {          
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                var msg = ex.Message;
            }
            finally
            {
                IsBusy = false;
            }
        }

我不明白延迟加载或滚动是如何工作的。有人可以帮忙吗?

解决方法

当您的页面加载时,您应该调用您的服务来加载前 X 行数据。假设 X=50 - 它可以是您想要的任何值。

当用户滚动到列表底部时,CollectionView 将触发 RemainingItemsThresholdReachedCommand。当它触发时,您应该从您的服务中提取下 X 个项目并将它们添加到您的 ItemsSource

为此,您的服务需要能够增量加载数据。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...