21

你能解释一下的getView()方法ArrayAdapter

我阅读了文档,它具有三个参数:

  • position:我们想要查看的项目的适配器数据集中项目的位置。
  • convertView:如果可能的话,要重用旧视图。注意:在使用之前,您应该检查此视图是否为非空且类型合适。如果无法将此视图转换为显示正确的数据,则此方法可以创建一个新视图。
    异构列表可以指定其视图类型的数量,以便此视图始终是正确的类型(参见 getViewTypeCount() 和 getItemViewType(int))。
  • parent:此视图最终将附加到的父级

我理解了position参数。就像他们说的那样,它暗示了项目的位置,谁被请求查看。

究竟convertView从何而来。我见过很多例子,他们检查是否convertView为空。如果 is 为 null,它们会扩充行布局的新实例,填充并返回它。我想我也明白了这一点,但有一件事仍然让我感到困惑。convertView通过参数传入的布局是什么。如果是初始化时传入resourceArrayAdapter参数?是由返回的最后一个布局的缓存副本getView()吗?

最后。参数有什么作用parent。我还没有看到太多使用这个的例子。他们中的大多数只是简单地重用/膨胀行布局并返回它。

(我问是因为我的 . 中有一个点击动画ListView。特别是这个旨在复制 Spotify 的下拉快速操作菜单的动画。我的动画有点迟钝。在诊断了这个问题一段时间后,我意识到这是因为我的getView()方法需要一些时间来完成,因为我在每次迭代中都在膨胀一个新的行布局。有人建议在一段时间内缓存行布局,ViewHolder而其他示例指向重用convertView参数,即只膨胀一个如果convertView为空,则行布局。)

4

2 回答 2

44

是 getView() 返回的最后一个布局的缓存副本吗?

convertView是离开屏幕的行的视图(因此它不是该getView方法返回的最后一个视图)。例如,首先显示列表,在这种情况下convertViewnull,之前没有构建任何行视图并离开屏幕。如果向下滚动,第 0 行将离开屏幕(不再可见),当发生这种情况时,ListView可能会选择将该视图保留在缓存中以供以后使用(这是有道理的,因为 a 的行ListView通常具有相同的只有数据不同的布局)。将一些视图保存在缓存中并稍后使用它们的原因是getView方法可以被调用很多次(每次用户向上/向下滚动并且屏幕上出现新行时)。如果每次都需要重新创建行视图,这将导致创建大量对象,这是需要避免的。在您的getView方法中,您将检查convertView它是否是null. 如果是,null那么您必须构建一个新的行视图并用数据填充它,如果不是null,则为ListView您提供了以前的视图。拥有这个先前的视图意味着您不需要构建新的行布局,而是必须使用正确的数据填充它,因为该缓存视图仍然附加旧数据(您会在 stackoverflow 上看到很多问题用户问为什么他们的行ListView向下滚动时正在复制)。

父参数有什么作用。我还没有看到太多使用这个的例子。他们中的大多数只是简单地重用/膨胀行布局并返回它。

它应该用于LayoutParams为新膨胀/构建的行获取正确的信息。例如,如果您对一个以 aRelativeLayout为根的布局进行膨胀,并且您不使用parent来获取LayoutParams该行布局,那么您可能会遇到一些问题。考虑到父母,您将使用:

convertView = getLayoutInflater().inflate(R.layout.row_layout, parent, false);
于 2012-09-13T06:28:29.287 回答
2

我的理解convertView是,它本质上是被回收的视图,因为它们目前没有被使用——例如,你向下滚动列表,顶部的那些不在屏幕上,所以它们被传递到这个当您需要新视图时使用的参数(因此您不必创建一个全新的视图而让未使用的视图闲置)。iOS 有一个类似的方法叫做dequeueReusableCellWithIdentifier. 如果列表视图的每一行都具有相同的结构,则可以安全地将其转换为适当的类型并仅更新其中的信息 - 文本、图像等。它将是先前通过getView()调用相同列表返回的视图.

我最好的猜测(当然这是一个猜测)parent是这个适配器的列表是它的子视图。如果您需要上下文、访问资源系统、将信息传递到列表的父视图或从列表的父视图接收信息,它会为您提供返回渲染系统的路线。

于 2012-09-13T06:28:40.253 回答