ArrayAdapter 的 getView() 方法的说明

您能解释一下.getView()ArrayAdapter

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

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

我理解了这个参数。就像他们说的,这意味着项目的位置,谁被请求了视图。position

从何而来。我见过很多例子,他们检查是否为空。如果 is 为 null,则它们会膨胀行布局的新实例,填充该实例并返回该实例。我想我也已经明白了,但有一件事仍然让我感到困惑。通过参数传入的布局是什么。是 if 在初始化 ArrayAdapter 时传入的资源参数吗?是否返回了 上一个布局的缓存副本?convertViewconvertViewconvertViewgetView()

最后。该参数的作用。我没有看到太多的例子来利用这一点。他们中的大多数只是重用/膨胀行布局并将其返回。parent

(我问,因为我的.特别是这个旨在复制Spotify的下拉快速操作菜单。我的动画有点迟钝。在诊断了这个问题一段时间后,我意识到这是由于我的方法需要一点时间才能完成,因为我在每次迭代中都会膨胀新的行布局。有人建议缓存行布局,而其他示例指出重用参数,即如果为 null,则仅膨胀行布局。ListViewgetView()ViewHolderconvertViewconvertView


答案 1

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

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

父参数的作用。我没有看到太多的例子来利用这一点。他们中的大多数只是重用/膨胀行布局并将其返回。

它应该用于获得新膨胀/构建的行的正确性。例如,如果您夸大了一个以 a 作为根的布局,并且不使用 来获取 ,则行布局可能会遇到一些问题。要考虑父级,您可以使用:LayoutParamsRelativeLayoutparentLayoutParams

convertView = getLayoutInflater().inflate(R.layout.row_layout, parent, false);

答案 2

我的理解是,它本质上是已被回收的视图,因为它们目前没有被使用 - 例如,您向下滚动列表,顶部的视图不在屏幕上,因此当您需要新视图时,它们会传递到此参数中以供使用(因此您不必在闲置时创建一个全新的视图)。iOS有一个类似的方法,称为。如果列表视图的每一行都具有相同的结构,则可以安全地将其转换为适当的类型,然后只更新其中的信息 - 文本,图像等。它将是以前通过调用同一列表返回的视图。convertViewdequeueReusableCellWithIdentifiergetView()

我最好的猜测(诚然,这是一个猜测)是这个适配器的列表是一个子级的观点。如果您需要上下文(对资源系统的访问权限)将信息传递到列表的父视图或从列表的父视图接收信息,它将为您提供返回呈现系统的路由。parent


推荐