为啥我的收藏视图在向下或向上滚动时很慢?如何解决性能问题?我已经清理了我的 UI 代码
Posted
技术标签:
【中文标题】为啥我的收藏视图在向下或向上滚动时很慢?如何解决性能问题?我已经清理了我的 UI 代码【英文标题】:Why my collectionview is slow when scrolling down or up? how to fix performance issue? I already Cleaned my UI Code为什么我的收藏视图在向下或向上滚动时很慢?如何解决性能问题?我已经清理了我的 UI 代码 【发布时间】:2021-08-17 03:55:01 【问题描述】:为什么我的收藏视图在向下或向上滚动时很慢?如何解决性能问题?
我阅读了所有关于此的帖子,他们主要说要清理您的 UI 代码。如果 UI 代码复杂,它会运行缓慢。有道理。
但是在这里我已经清理了我的代码。我在这里无能为力。
在 collectionview 我有一个标签和图像。我将标签和图像路径存储在数据库中。图像存储在 appdata 目录中
我认为某些原因导致性能问题,但我不确定是什么原因?
<ContentPage.Content>
<StackLayout Padding="15" HorizontalOptions="CenterAndExpand">
<!-- CollectionView -->
<CollectionView ItemsSource="Binding MyList"
SelectionMode="Single"
SelectedItem="Binding ItemSelectedEvent, Mode=TwoWay"
SelectionChangedCommand="Binding SelectionChangedCommand"
ItemSizingStrategy="MeasureAllItems"
BackgroundColor="Transparent">
<!-- Body -->
<CollectionView.ItemTemplate>
<DataTemplate>
<ContentView>
<grid>
<Frame CornerRadius="15" HasShadow="True" Padding="0" BackgroundColor="Black">
<StackLayout>
<StackLayout HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Label Text="Binding CardType"
HorizontalTextAlignment="Center"
BackgroundColor="Black"
TextColor="white"></Label>
</StackLayout>
<!-- Image -->
<StackLayout HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Image Source="Binding CardFrontURL"
Aspect="AspectFill"
HorizontalOptions="Fill"
VerticalOptions="Fill"></Image>
</StackLayout>
</StackLayout>
</Frame>
</grid>
</ContentView>
</DataTemplate>
</CollectionView.ItemTemplate>
<!-- Header -->
<CollectionView.Header>
<StackLayout Orientation="Horizontal" HorizontalOptions="Center">
<Label Text="Cards List" TextColor="Black" VerticalOptions="Center" FontSize="14" FontAttributes="Bold" />
</StackLayout>
</CollectionView.Header>
</CollectionView>
</StackLayout>
</ContentPage.Content>
在列表中存储标签和图像
public ObservableRangeCollection<MyModel> MyList get; set;
【问题讨论】:
CardFrontURL
是 url 还是文件路径?
CardFromURL 只是一个字符串。此字符串是手机上存储图像的 appdata 文件夹的路径
我看到您已编辑问题以删除 ContentView
和 Grid
。现在,那些StackLayout
s 呢? [请勿将它们从您的问题中编辑出来-这样做会使此问答对将来的任何人都无用-只需报告是否按照我的说明进行操作,以制作不需要太多它们的更简单的布局,从而显着加快滚动速度,或不是。] 如果布局结果不是原因,那么就说 - 我们会知道我的回答在这种情况下不相关。
【参考方案1】:
第一步是查明是Image
s 还是您的DataTemplate
导致了减速。
测试:删除图像 - 注释掉 <Image Source ...>
。
它运行得更快吗?然后阅读有关获取和“缓存”图像的信息,以便可以快速渲染它们。
如果不是图片,那就是你的ItemTemplate
的结构。
为每个项目创建一个ContentView
、一个Grid
和三个StackLayout
s。每个项目有五个 Layout
类。
几乎不需要像在原始代码中那样嵌套所有垂直的StackLayout
s。为什么你认为你需要这些?你为什么不简单地拥有一个StackLayout
,并将Label
和Image
都放入其中?
同样,为什么你有Grid
?它对你有什么用?
“干净的 UI”在每个项目中使用尽可能少的 Layout
类。
我相信你可以将这五个减少到一个Layout
:
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame Padding="0,0,0,10" ...>
<StackLayout>
<Label Text="Binding CardType" .../>
<Image HeightRequest="200" Source="Binding CardFrontURL" .../>
</StackLayout>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
您可能需要在某些项目上使用Padding
或Margin
,以提供StackLayout
s 提供的垂直间距。
AFAIK,无需添加另一个 Layout
类总是可以获得所需的间距。
最坏的情况是,您将BoxView
添加到HeightRequest
和BackgroundColor="Transparent"
。
注意:<Image HeightRequest="200" ...
- 如果固定高度满足您的需要,这允许布局逻辑在读取图像源之前确定项目高度,这有助于使滚动平滑。没有这个,当您第一次滚动列表时,可能会出现一个或多个“打嗝”(“口吃”,短暂的停顿),同时获取所需的图像。
或使用Grid
,以便将来获得更大的灵活性:
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame Padding="0,0,0,10" ...>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Text="Binding CardType" .../>
<Image Grid.Row="1" Source="Binding CardFrontURL" .../>
</Grid>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
Grid
很棒,因为您可以通过添加行和列来表示相当精细的布局,并且仍然只有一个布局类。
【讨论】:
很好的提示,谢谢!!!我从中学到了很多。我做了所有这些改变。所以现在它的滚动很顺利。但是向下滚动,它现在只卡住了一次。这比以前顺畅多了! @StarGates - 甜!很高兴这有帮助。 @StarGates - 改善“卡住一次”的情况,可能需要预缓存图像。当您的页面首次加载时,您会启动一个后台线程,该线程开始获取图像 URL,并将这些图像存储在字典中。正确处理有点棘手,因为您有一个后台线程添加到字典中,而前台 (UI) 正在尝试从字典中读取。如果它还没有在字典中,您必须优先获取所需的优先级。未来的主题供您探索。 :) @StarGates - 如果您将HeightRequest="NN"
添加到Image
,其中NN 表示您确定有用的某个特定值,例如“50”,那么布局逻辑可以在读取之前确定项目高度图片来源。这可能有助于解决一次性故障。
另外,将VerticalOptions
移至Fill
以使其流畅以上是关于为啥我的收藏视图在向下或向上滚动时很慢?如何解决性能问题?我已经清理了我的 UI 代码的主要内容,如果未能解决你的问题,请参考以下文章