动态创建的 ListView 项的视图持有者模式

View holder pattern for dynamically created ListView items

我知道当你使用 ListViewArrayAdapter 和布局资源时,你应该使用视图持有者模式重用 convertView 以改进例如滚动的平滑度。

如果 ListView 的项目是动态生成的,例如使用 new RelativeLayout(context) 并使用 addView() 添加内容怎么办?在这种情况下,我应该使用类似于视图持有者模式的东西来重用 RelativeLayout 吗?我的意思是这样的。

RelativeLayout relativeLayout = (RelativeLayout) convertView.getTag();
relativeLayout.removeAllViews();
// Now add all the required Views.

使用视图持有者模式来避免实例化 RelatativeLayout 的新实例是合理的,或者是使用视图持有者模式来避免从膨胀的资源中调用 findViewById 的主要原因?

是的,您绝对应该仍然使用 ViewHolder。手动创建视图的场景和你inflate时没有太大区别。

Is using a view holder pattern to avoid instantiating a new instance of RelatativeLayout justified or is the primary reason for using the view holder pattern to avoid all the calls to findViewById from an inflated resource?

实际上,您通过检查 getView(int position, View convertView, ViewGroup parent)convertView 参数来避免 RelativeLayout(或其他)的冗余实例化 null,当您手动创建视图。

您仍然需要一种方法来访问您的子视图(TextViews 或您有什么),因此您将使用手动制作的 ID 或标签进行搜索或使用 ViewHolder 存储对象引用(当然更快)

我同意@ivan-bartsov 的观点,并补充说,inflation 和通过 id 查找视图这两个操作都很昂贵,这也是为什么要采用 ViewHolder 模式的原因。

我也想提一下。如果您的视图组合数量有限,比如说 1、2、3 甚至 4,那么覆盖 Adapter.getViewTypeCountAdapter.getItemViewType 将是一个很好的主意,这样您就可以利用针对不同项目布局的内置 ViewHolder/Recycling 功能。该框架将正确地为您提供给定位置的正确 convertView。

最后一点,有时数据的结构方式使用 ExpandableListView 或类似的小部件更有意义,这些小部件将为子视图提供开箱即用的视图回收,因此您不需要不必自己给它们充气。