优化ListView可以采取哪些步骤?
优化ListView可以采取哪些步骤?
我有一个绑定到ListView的ObservableCollection。这个列表基本上是一组选项。如果你点击其中一个,它的状态会改变。它会被添加到收藏夹中并显示在收藏夹列表中(也是一个ListView),或者它会从收藏夹中移除。
这是我的应用程序的主要功能,所以会有很多添加和移除操作。当更新时,这两个列表都会变得缓慢、有问题和闪烁。
我该如何使它更快/流畅?
我尝试在工作线程上运行所有的添加/移除调用。我尝试使用Task和async函数(实际上使情况更糟)。在这种情况下有一个“正确”的实现方法吗?(ListView在UI线程上,工作线程使其保持更新)有没有一篇文章可以教我良好的做法?
实现:
注意:Truck是另一个存储数据的类。
来自Data类:
Listtrucks = new List (); public void addToFavorites(Truck truck) { foreach(Truck t in trucks) { if(t == truck) { t.setFavorite(true); } } } public void removeFromFavorites(Truck truck) { foreach (Truck t in trucks) { if (t == truck) { t.setFavorite(true); } } } public List getTrucks() { return trucks; } public List getFavoriteTrucks() { List temp = new List (); foreach(Truck t in trucks) { if (t.isFavorite()) { temp.Add(t); } } return temp; }
来自显示所有Trucks的页面:
public partial class AllPage : ContentPage { public AllPage(csharp.Data data) { //初始化 InitializeComponent(); this.data = data; //构建列表 refreshAsync(); ListView list = new ListView() { ItemTemplate = new DataTemplate(typeof(csharp.PlateCell)), ItemsSource = trucks, IsPullToRefreshEnabled = true, }; //选择 list.ItemSelected += (sender, e) => { if (e.SelectedItem == null) return; //行取消选择,不执行任何操作 var selection = e.SelectedItem as csharp.Truck; if (selection.isFavorite()) { data.removeFromFavorites(selection); selection.setFavorite(false); } else { data.addToFavorites(selection); selection.setFavorite(true); } ((ListView)sender).SelectedItem = null; //取消选择行 refreshAsync(); }; list.RefreshCommand = new Command(() => { //trucks = data.getFavoriteTrucks(); refreshAsync(); list.IsRefreshing = false; }); //将列表添加到页面 root.Children.Add(list); }//构造函数结束 csharp.Data data; ObservableCollectiontrucks = new ObservableCollection (); private async Task refreshAsync() { await Task.Run(() => refreshThread()); } private void refreshThread() { List all = data.getTrucks(); trucks.Clear(); foreach (csharp.Truck t in all) { trucks.Add(t); } } }
问题的出现原因:
- 可能没有使用虚拟化技术,导致ListView性能下降;
- 可能在非GUI线程中更新了ObservableCollection,导致出现问题;
- 可能没有使用MVVM模式,导致代码结构混乱;
- 可能每次都重新填充整个列表,而不是仅传播更改。
解决方法:
- 学习和使用虚拟化技术;
- 避免在非GUI线程中更新ObservableCollection;
- 学习和使用MVVM模式;
- 只传播更改而不是重新填充整个列表;
- 使用SmartCollection来避免多次触发CollectionChanged事件;
- 确保ObservableCollection中的项生成PropertyChanged事件以更新UI。
以下是整理后的文章:
为了优化ListView的性能,我们可以采取以下步骤:
1. 学习和使用虚拟化技术。虚拟化可以提高ListView的性能,避免加载大量数据时出现卡顿。你可以参考相关链接:Virtualizing。
2. 避免在非GUI线程中更新ObservableCollection。如果在其他线程中更新ObservableCollection,可能会导致问题。你可以参考这个链接:this。
3. 学习和使用MVVM模式。MVVM模式可以帮助我们更好地组织代码,提高代码的可读性和可维护性。你可以参考这个链接:MVVM。
4. 只传播更改而不是重新填充整个列表。如果每次都重新填充整个列表,会导致性能下降。我们应该关注如何仅传播更改以利用虚拟化。你可以参考这个链接:this。使用SmartCollection可以确保只触发一次CollectionChanged事件,而不是在每个添加的项上触发。
5. 确保ObservableCollection中的项生成PropertyChanged事件以更新UI。如果ObservableCollection中的项发生更改但没有生成PropertyChanged事件,UI将不会更新。一个好的方法是让所有的ViewModel(在这种情况下是truck)从一个实现了INotifyPropertyChanged接口的ViewModel基类继承。属性的Set方法应该生成PropertyChanged事件。你可以参考这个链接:INotifyPropertyChanged。
希望以上方法能够帮助你优化ListView的性能。如果还有其他问题,欢迎再次提问。
问题的原因:
1. ListView在Android上的滚动不流畅。
2. 使用ListViewCachingStrategy.RecycleElement时,更改ViewCell的布局后UI不会更新。
3. ViewCell中包含过多的图像、标签和布局,导致性能下降。
4. 使用Xamarin Forms编写ViewCell比使用原生代码性能差。
解决方法:
1. 尝试使用FastCell库来实现流畅的滚动效果。
2. 限制ListView中的项的数量。
3. 启用ListViewCachingStrategy.RecycleElement来提高性能,但需要注意更改ViewCell布局后UI不会更新的问题。
4. 尽量简化ViewCell中的内容,减少图像、标签和布局的数量。
5. 在ViewCell中使用AbsoluteLayout来减少布局计算的数量。
6. 考虑使用原生代码编写ViewCell,以提高性能。
7. 实现INotifyPropertyChanged接口以改善性能。
8. 将ListView的hasUnevenRows属性设置为false以提高性能。
9. 避免在实例化后设置ListView的可见性或颜色,以避免性能损失。
希望这些方法能帮助到你,如果有其他调整,请让我知道。谢谢!