在自定义项面板中实现 UI 虚拟化



我的目标是显示一些布局,例如官方Android Imgur应用程序,其中项目具有固定宽度但可变高度。我已经有一个带有GridView的自定义面板.它有效。但是,它破坏了几件事:

  1. 我没有得到 UI 虚拟化。当需要渲染大量图像时,这是一个很大的性能瓶颈。
  2. 由于虚拟化已消失,因此也不支持增量加载。

我搜索了很多,但找不到任何有关如何实施虚拟化的文档。所以,我有几个问题:

  1. 甚至可以使用自定义面板实现虚拟化吗?如何?
  2. 是否可以使用现有的面板之一(例如VirtualizedStackPanel)来获得我需要的布局?

我认为您无法在自定义面板上获得虚拟化。我上一次需要自定义的虚拟化面板是在 Windows 照片应用中看到的原型中,我从头开始完成了所有虚拟化。然后我看到两个选项:

  1. 自己实现虚拟化 - 在ScrollViewer中放置一个面板(Canvas效果很好,但您也可以使用自定义面板),创建一些容器来填充几个屏幕的项目,并在滚动时重新排列容器及其内容以始终在实现窗口中有一些项目。这很有趣,您可以获得惊人的性能,尤其是在后台线程上预先计算和缓存项目的布局时。您可能需要付出一些努力来处理焦点、键盘输入(无论窗口位置如何,您都应该始终保持焦点容器实现)或可能的可访问性,但这将是值得的。
  2. 在常规ListView中使用自定义面板,但不要更改ListView.ItemsPanel - 将其保留为默认值 ( ItemsStackPanel ),并将自定义布局面板放在项模板内,并具有这些面板的高但不同的行。这意味着您的布局不会到处都是锯齿状的 - 项目需要与某处的ListViewItems对齐,但实现基础知识要简单一些。我认为这就是照片应用程序中的布局的工作方式。您需要付出大量努力来覆盖ListView处理输入和显示选择视觉对象的方式,但它可能适合您。请记住,在这种情况下,您的ItemsSource将需要具有一组项目才能在每个ListViewItem中执行自定义布局。

我会选择第一个选项,但这取决于你。最初需要做更多的工作,但总的来说,它最终可能会更容易正确,让你自由地布置东西,没有任何行,它会教你一些有用的东西。第二个选项只是意味着您必须掩盖您无论如何都不需要的内置行为。我认为第一个选项还可以更好地将视图层与视图模型分开,因为ItemsSource中不需要依赖于布局的分组,除非您实现某种视图层聚合器ItemsSource来处理视图模型中的项目。

在这篇精彩的文章中阅读有关虚拟化的一些理论和实践的更多信息:

列表视图基础知识和虚拟化概念

最新更新