Xamarin.Forms CollectionView Infinite Scroll 在一段时间后冻结

Posted

技术标签:

【中文标题】Xamarin.Forms CollectionView Infinite Scroll 在一段时间后冻结【英文标题】:Xamarin.Forms CollectionView Infinity Scroll freezed after sometime 【发布时间】:2021-05-26 15:53:35 【问题描述】:

我使用 CollectionView 和 ItemSource=Photos 制作了一个滚动应用程序,在滚动一段时间后,应用程序被冻结了。 这是我的 ViewModel 包含所有元素的 counstructor 代码:

        public MainPageViewModel()
        
            CounterData = 20;
            StandartCounter = 20;
            LoadPhotosCommand = new Command(execute: async () => await ExecuteGetAllPhotos());
            LoadRefreshCommand = new Command(execute: async () => await ExecuteRefreshGetAllPhotos());
            LoadNewPhotosCommand = new Command(execute: async () => await ExecuteGetNewPhotos());
            LoadSelectedPhotoCommand = new Command(execute: async () => await ExecuteGetDetailsSelectedPhoto());
            Photos = new ObservableCollection<Photo>();
            PhotosAll = new ObservableCollection<Photo>();
            PhotosModel = new PhotosModel();
            SelectedPhoto = new Photo();
        

这是我在ViewModel 中的逻辑,此函数从 API 获取所有照片 - 将它们存储在 PhotosAll 列表中,并将 20 个元素添加到作为 collectionView 的 ItemSource 的 Photos 列表中:

        async Task ExecuteGetAllPhotos()
        
            if (IsBusy)
                return;      
            try
            
                IsBusy = true;
                Photos.Clear();
                PhotosAll.Clear();
                PhotosModel = await InstagramCloneDataStore.GetAllPhotos();
                if (PhotosModel != null)
                
                    foreach (var photo in PhotosModel.Photos)
                    

                        PhotosAll.Add(photo);
                    

                    foreach (var el in PhotosAll.Skip(0).Take(StandartCounter))
                    
                        Photos.Add(el);
                    
                    CounterData = StandartCounter;
                
            
            catch (Exception ex)
            
                Debug.WriteLine(ex);
                var msg = ex.Message;
            
            finally
            
                IsBusy = false;
            
        

这是来自 RemainingItemsThresholdReachedCommand 的函数,其逻辑是当用户滚动 20 个项目时读取新的 20 个项目并将它们添加到 Photos 列表中。

         async Task ExecuteGetNewPhotos()
        
            if (IsBusy)
                return;
            try
            
                IsBusy = true;
                await Task.Delay(100);
                foreach (var el in PhotosAll.Skip(CounterData).Take(StandartCounter))
                
                    Photos.Add(el);
                
                CounterData += StandartCounter;
            
            catch (Exception ex)
            
                Debug.WriteLine(ex);
                var msg = ex.Message;
            
            finally
            
                IsBusy = false;
            
        

刚开始滚动非常好,但过了一段时间后应用程序被冻结了。有没有人有同样的问题?或者对此有什么解决方案?

更新 看起来Photos 列表看起来更大,加载新项目变得越来越慢

【问题讨论】:

我在尝试使用数千个项目构建嵌套 CollectionView 时遇到了同样的问题。滚动时,应用程序会冻结几秒钟。对于我自己,我通过拒绝使用CollectionView 并结合StackLayoutelements 手动构建视图来解决问题。这不是一个理想的解决方案,因为我在出现视图时有启动延迟,因此需要进行某种虚拟化,但这种方法对我来说更可取。 @Miamy 可以发一些代码示例吗? 你可以在这里找到它:github.com/Miamy/MyPlayer/blob/master/MyPlayer/Views/…。请注意,这是一个非常原始的原型,将被重新设计,但您可以了解手动视图构建的主要思想。 【参考方案1】:

在审查我的代码几个小时后,我学到了 2 件事:

    RemainingItemsThreshold="Binding CounterData" -> CounteData 是静态值,无法更改。 我为skip 实现了一个值,或者你可以使用CounterData 或者我使用StandartCounter,还有一个值用于计算我称为RailCounter 的大列表中的当前元素位置。 你每次都从PhotosAll.Skip(RailCounter).Take(StandartCounter)RailCounter += StandartCounter; 问题是 CounterData 必须是静态的!

【讨论】:

感谢分享。不要忘记接受答案。

以上是关于Xamarin.Forms CollectionView Infinite Scroll 在一段时间后冻结的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.Forms 手势密码实现

Xamarin.Forms 和 Xamarin Native 有啥区别? [关闭]

如何使用 Xamarin.Forms.Maps(无 Xamarin.Forms.GoogleMaps)在地图中应用样式或更改颜色

Xamarin Forms Prism:prism ResourceDictionary 中已存在具有键“Xamarin.Forms.NavigationPage”的资源

Xamarin.Forms.Forms.Init(e) Onlaunched 中的 FileNotFoundExeception

如果调用方未使用 Xamarin.Forms,Xamarin 依赖项服务能否正常工作?