【问题标题】:Xamarin Forms ListView PerformanceXamarin 表单 ListView 性能
【发布时间】:2018-03-08 22:57:15
【问题描述】:

我的应用中有一个 Xamarin.Forms ListView,而这个 ListView 使用由 DataTemplateSelector 选择的不同 ItemTemplates。使用某些模板效果很好,但其中一些模板会产生性能问题。这是一个坏模板的代码:

<DataTemplate x:Key="Template1">
    <ViewCell>
        <Grid Padding="10,0,10,0">
            <Grid.Resources>
                <ResourceDictionary>
                    <Style TargetType="Label" BasedOn="{StaticResource LabelStyle}"/>
                    <Style TargetType="BoxView" BasedOn="{StaticResource InactiveStyle}"/>
                </ResourceDictionary>
            </Grid.Resources>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Image Grid.Column="0" Grid.RowSpan="3" Source="Icon.png" HeightRequest="30" WidthRequest="30" Margin="0,0,10,0" VerticalOptions="Center" HorizontalOptions="Center"/>

            <BoxView Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" IsVisible="{Binding Inactive}"/>
            <Label Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" x:Name="Label1" Text="{Binding Column1}" FontAttributes="Bold"/>

            <BoxView Grid.Column="1" Grid.Row="1" IsVisible="{Binding Inactive}"/>
            <Label Grid.Column="1" Grid.Row="1" Text="{Binding Column2}" HorizontalOptions="Start"/>

            <BoxView Grid.Column="2" Grid.Row="1" IsVisible="{Binding Inactive}"/>
            <Label Grid.Column="2" Grid.Row="1" Text="{Binding Column3}" HorizontalOptions="End"/>

            <BoxView Grid.Column="1" Grid.Row="2" IsVisible="{Binding Inactive}"/>
            <Label Grid.Column="1" Grid.Row="2" Text="{Binding Column4}" HorizontalOptions="Start" />

            <BoxView Grid.Column="2" Grid.Row="2" IsVisible="{Binding Inactive}"/>
            <Label Grid.Column="2" Grid.Row="2" Text="{Binding Column5}" HorizontalOptions="End"/>
        </Grid>
    </ViewCell>
</DataTemplate>

我也发现了这个:Xamarin ListView Performance,但我无法让它滚动得更快。看起来它无法足够快地创建单元格,以至于列表滚动生涩(Android和iOS)。我能做些什么来更快地做到这一点?

编辑: 我切换到CachingStrategy="RetailElement" 并且能够优化一些东西。但总是在调用 OnSelectTemplate 方法时滚动变慢。即使此方法确实只在第一行返回一个模板。所以对我来说,这看起来模板需要很长时间才能构建。但我不知道为什么:(

【问题讨论】:

  • 您能否发布一张ListView 外观的屏幕截图?如果可能的话,将有助于简化DataTemplate。你也在设置CachingStrategy吗?
  • 嗯,前面有 3 行 3 行包含文本和一个图像。如果文本处于非活动状态,则 boxviews 只是用来删除文本
  • 您可以尝试使用具有IsStrikeThrough 属性的XLabs' ExtendedLabel。这将摆脱所有那些BoxView 元素。摆脱尽可能多的元素应该会有所帮助。
  • 您是否尝试过删除部分视图以查看可能对性能产生影响的因素?例如,尝试删除图像(仅作为测试)。了解布局的哪些部分显着减慢速度有助于确定下一步该做什么。此外,根据您的布局,您应该能够为第一列的宽度分配一个常量,这将导致比自动更快的布局时间。
  • 我删除了BoxViewImage。但它并没有变得更快。查看我编辑的问题

标签: c# xamarin xamarin.ios xamarin.forms xamarin.android


【解决方案1】:

关于滚动,您需要激活相应的 RecyclingMode:

<ListView CachingStrategy="RecycleElement">

如果您使用 DataTemplate 选择器,请使用:

 <ListView CachingStrategy="RecycleElementAndDataTemplate" />

您可能需要调整您的 DataTemplate 创建过程。但是使用这种技术,OnSelectTemplate 只会在必要时被调用。

此外,如果这还不够,您或许应该根据 Inactive 状态使用 DataTemplateSelector 逻辑将您的 dataTemplate 拆分为 2,以避免对元素的 IsVisible 绑定可能很昂贵。

【讨论】:

  • 我已经尝试过CachingStaregy,但我现在会尝试移除非活动状态
  • 可能会快一点,但距离本机速度还是有很大差距
  • 当你说它慢时:是加载慢还是操作慢?我很惊讶:我的应用程序有很多列表并且没有性能问题。您可以尝试调试您的 DataTemplateSelector 以确保它不会被调用太多时间:应为每个加载的单元格调用 OnSelectTemplate 方法。
  • 您的 ItemsSource 绑定到列表或 ObservableCollection?
  • 感谢您的帮助。我发现,TemplateSelector 在启动时被调用了 1500 次(集合中有 50 个项目),滚动时每个项目被调用两次
【解决方案2】:

对于Xamarin.Form Listview 性能的最佳选择,您可以使用自定义渲染器使用本机视图。

以下是自定义渲染器示例的链接。

https://github.com/xamarin/xamarin-forms-samples/tree/master/CustomRenderers/ListView

【讨论】:

  • 我只会在绝对没有其他选择的情况下使用它。不过谢谢
  • 当我决定使用 CustomRenderers 时,是否可以使用现有的 XAML 模板?
  • 不,您需要创建本地单元格并在您的 Listview Viewcell 中进行渲染。而且自定义渲染器更快。
【解决方案3】:

对于初学者,将资源字典从模板内部移动到包含页面。

然后,就像其他人所说的:

  1. 使第一列固定宽度
  2. 用您自己的实现删除线的自定义标签替换 boxviews
  3. 使用缓存策略

【讨论】:

  • 我按照你说的做了,而且确实变得更快了。但它仍然没有达到应有的速度。
  • 我唯一可以建议的另一件事是尝试新版本的 Xamarin Forms 2.4.0 并试用新的 Android 快速渲染器。
  • 谢谢!之前没有注意到 FastRenderers。但不幸的是,它似乎对我没有任何影响
猜你喜欢
  • 1970-01-01
  • 2018-03-11
  • 2016-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多