【问题标题】:Xamarin.Forms implement Lazy Loading in CollectionViewXamarin.Forms 在 CollectionView 中实现延迟加载
【发布时间】:2021-05-25 21:14:59
【问题描述】:

这是我的 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 行数据并将它们添加到你的 ObservableCollection 中。文档解释得很清楚 - docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/…
  • 我真的无法理解
  • 什么具体你不明白?您的服务是否能够接受允许其返回数据子集的参数?如果不是,那是你需要改变的第一件事
  • @Jason 我有 ObservableCollection 一个从 API 读取的列表。当RemainingItemsThresholdReachedCommand="{Binding LoadNewPhotosCommand}" 被调用时如何处理列表?
  • 从您的服务中加载更多数据,然后将它们添加到 ObservableCollection

标签: c# xamarin.forms xamarin-community-toolkit xamarin.forms.collectionview


【解决方案1】:

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

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

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

【讨论】:

  • 我有一个 ObservableCollection AllPhotos 有 5000 个数据条目。并生成另一个ObservableCollection PhotoSequence,他每次都可以从AllPhotos 获得50 个项目并绑定到CollectionView 的源。这是你的主意吗?
  • 不,一次性获取 5000 个项目是导致您的应用挂起的原因。别那样做。而是使用增量加载以块的形式请求它们,以提高性能。
  • 我必须首先从 API 获取所有项目。速度很快,慢的部分是渲染所有 5000 个项目
  • 我无法理解如何从 API 中按顺序获取数据。你试图告诉我
  • 好的,然后试试你在第一条评论中的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
相关资源
最近更新 更多