【问题标题】:Why does the Android View API care about an ArrayAdapter's getViewTypeCount?为什么 Android View API 关心 ArrayAdapter 的 getViewTypeCount?
【发布时间】:2012-05-03 10:58:13
【问题描述】:

我一直在学习如何创建自定义 ArrayAdapters,并熟悉了重写 ArrayAdapter 的 getViewTypeCountgetItemViewType 方法。

为什么 Android View API 关心 getViewTypeCount 返回的“可能的视图类型数量”?而且,作为程序员,为什么要关心?

【问题讨论】:

标签: android android-listview android-arrayadapter recycle


【解决方案1】:

我刚刚查看了 Android 源代码以确切了解 getViewTypeCount 的使用位置。它在抽象的AbsListView类'内部RecycleBin类'setViewTypeCount方法中。

这个setViewTypeCount方法用于指定scrapViewsArrayList<View>的初始大小。这个ArrayList 本身是ArrayList<View>s 中的ArrayList——每个“视图类型计数”一个。

此外,getViewTypeCount 返回的值被赋值给RecycleBin 的成员变量mViewTypeCount。该成员用于控制 RecycleBin 类中的少数方法中只有一个视图与多个视图的情况下的回收逻辑(正如每个人都在暗示的那样)。

所以答案是,我相信getViewTypeCountRecycleBin 使用,以便它知道它是否只有一个或多个视图要处理。可以这么说。

(感谢大家让我睁开眼睛回收并激励我阅读源代码。)

【讨论】:

    【解决方案2】:

    Commonsware 对您上一个问题的回答很好地解释了为什么您需要关心这些方法。这是一个小例子:

    您有一个ListView,其中包含 100 行和 3 种类型的行:

    1. 一个简单的TextView
    2. 自定义视图(非常复杂)
    3. AnalogClock 视图

    ListView是这样开头的:

    • 位置 0:TextView 第一个可见位置
    • 位置 1:自定义视图
    • 位置 2:自定义视图
    • 位置 3:文本视图
    • 位置 4:AnalogClock 最后可见位置
    • 位置 5:自定义视图 第一个不可见位置(这里 android 将提供一个回收视图)
    • 位置 6:文本视图

    如果您不实现这些方法,那么 android 将简单地回收视图而不考虑行的类型。所以在上面的例子中,当用户向下滚动ListView 时,getView 方法将被调用用于行5 并具有回收视图(行 0 不再可见),TextView(@对于此职位,987654330@ 将不是 null)。如您所见,这不是您在该位置所期望的视图。因为在getView 方法中你有这样的东西:

       //...
           if (convertView == null) {     
              // inflate views
           } else {
             //just use it    
       //...
    

    您最终会在应该是custom view(非常复杂)但得到一个简单的TextView 的行上设置数据。当您进一步上下滚动ListView 时,情况会变得更糟。

    如果您确实实现了这些方法,那么 android 将知道 getView 方法将需要 3 种类型的行。当需要显示第 5 行(来自上一个示例)时,android 将调用 getItemViewType 以查看 getView 方法期望该位置(位置 5)的视图类型。如果找到该类型的回收视图(以前回收),则将调用 getView 方法并将 convertView 设置为该回收视图,否则将调用 getView 并将 convertView 设置为 @987654344 @。当您滚动 ListView 以显示位置 5 时,(唯一)回收视图将是简单的 TextViewgetView 方法需要 custom view(非常复杂),因为在该类型中找不到回收的视图,所以 convertView 将是 null,你有机会膨胀它。

    如果您滚动 ListView 以显示位置 6,则位置 1 的视图(不再出现在屏幕上)将被回收,因此 ListView 现在有两个不同类型的视图(TextView 和一个custom view(非常复杂))。然后将再次调用getItemViewType,对于这个位置,getView 方法需要TextView。存在这种类型的回收视图,因此将调用 getView 方法并将 convertView 设置为此回收的 TextView。如果您进一步滚动 ListViewgetView 需要 TextViewcustom view 将提供这些回收视图之一(具有正确的类型)。此外,最终 AnalogCLock 类型的视图将被回收,因此 ListView 将拥有每个列表行类型的回收视图以重复使用。

    【讨论】:

    • 我真的很喜欢这个关于回收的解释。但是,这个答案与Why do recipes promote overriding getItemViewType and getViewTypeCount when it doesn't seem necessary? 更相关。我的问题是,具体来说,为什么自定义视图的数量很重要,每个 getViewTypeCount
    • @ybakos:“我的问题是,具体来说,为什么自定义视图的数量很重要,每个 getViewTypeCount ?” - 驱动它为回收而维护的对象池的数量,AFAIK。欢迎您筛选AdapterView代码以尝试获取更多详细信息。
    【解决方案3】:

    the reference, it says“每个类型代表一组可以在getView(int, View, ViewGroup)中转换的视图。”

    如果视图不同,则它们不能与不兼容的其他视图一起回收。因此,如果此方法返回与1 不同的任何内容,则标准的onView 回收代码将不再起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 2014-01-05
      • 2015-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多