优化ListView可以采取哪些步骤?

19 浏览
0 Comments

优化ListView可以采取哪些步骤?

我有一个绑定到ListView的ObservableCollection。这个列表基本上是一组选项。如果你点击其中一个,它的状态会改变。它会被添加到收藏夹中并显示在收藏夹列表中(也是一个ListView),或者它会从收藏夹中移除。

这是我的应用程序的主要功能,所以会有很多添加和移除操作。当更新时,这两个列表都会变得缓慢、有问题和闪烁。

我该如何使它更快/流畅?

我尝试在工作线程上运行所有的添加/移除调用。我尝试使用Task和async函数(实际上使情况更糟)。在这种情况下有一个“正确”的实现方法吗?(ListView在UI线程上,工作线程使其保持更新)有没有一篇文章可以教我良好的做法?

实现:

注意:Truck是另一个存储数据的类。

来自Data类:

List trucks = 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;
    ObservableCollection trucks = 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);
        }
    }
}

0
0 Comments

问题的出现原因:

- 可能没有使用虚拟化技术,导致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的性能。如果还有其他问题,欢迎再次提问。

0
0 Comments

问题的原因:

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的可见性或颜色,以避免性能损失。

希望这些方法能帮助到你,如果有其他调整,请让我知道。谢谢!

0