我试图确定最好的方法,有一个单一的ListView包含不同的布局为每一行。我知道如何创建一个自定义行+自定义数组适配器,以支持整个列表视图的自定义行,但如何在ListView中实现许多不同的行样式?


当前回答

In your custom array adapter, you override the getView() method, as you presumably familiar with. Then all you have to do is use a switch statement or an if statement to return a certain custom View depending on the position argument passed to the getView method. Android is clever in that it will only give you a convertView of the appropriate type for your position/row; you do not need to check it is of the correct type. You can help Android with this by overriding the getItemViewType() and getViewTypeCount() methods appropriately.

其他回答

ListView用于简单的用例,比如为所有行项创建相同的静态视图。 因为你必须创建ViewHolders并大量使用getItemViewType(),并动态显示不同的行项布局xml,你应该尝试使用RecyclerView来做,这是在Android API 22中可用的。它为多种视图类型提供了更好的支持和结构。

看看这个教程,了解如何使用RecyclerView来做你想要的事情。

因为你知道你会有多少类型的布局-这是可能的使用这些方法。

getViewTypeCount() -此方法返回列表中有多少类型的行

getItemViewType(int position) -根据位置返回应该使用哪种布局类型的信息

然后,只在布局为空时才膨胀布局,并使用getItemViewType确定类型。

更多信息请参阅本教程。

为了实现你在评论中描述的结构优化,我建议:

在名为ViewHolder的对象中存储视图。这将提高速度,因为您不必每次在getView方法中调用findViewById()。参见API演示中的清单14。 创建一个通用的布局,将符合所有的属性组合,并隐藏一些元素,如果当前位置没有它。

我希望这对你有帮助。如果您能够提供一些XML存根,其中包含数据结构和您希望如何将其映射到行的信息,那么我将能够给您提供更精确的建议。由像素。

如果我们需要在列表视图中显示不同类型的视图,那么最好在适配器中使用getViewTypeCount()和getItemViewType(),而不是切换视图view。不见了。在getView()中,VISIBLE是非常昂贵的任务,它会影响列表滚动。

请检查这一个在适配器中使用getViewTypeCount()和getItemViewType()。

链接:the-use-of-getviewtypecount

In your custom array adapter, you override the getView() method, as you presumably familiar with. Then all you have to do is use a switch statement or an if statement to return a certain custom View depending on the position argument passed to the getView method. Android is clever in that it will only give you a convertView of the appropriate type for your position/row; you do not need to check it is of the correct type. You can help Android with this by overriding the getItemViewType() and getViewTypeCount() methods appropriately.

我知道如何创建自定义行+自定义数组适配器,以支持整个列表视图的自定义行。但是一个列表视图如何支持许多不同的行样式呢?

你已经知道了基础知识。您只需要让自定义适配器根据所提供的行/游标信息返回不同的布局/视图。

ListView可以支持多种行样式,因为它派生自AdapterView:

AdapterView是一个视图,它的子视图是由适配器决定的。

如果你查看Adapter,你会看到使用特定行视图的方法:

abstract int getViewTypeCount()
// Returns the number of types of Views that will be created ...

abstract int getItemViewType(int position)
// Get the type of View that will be created ...

abstract View getView(int position, View convertView, ViewGroup parent)
// Get a View that displays the data ...

后两个方法提供了位置,因此您可以使用它来确定应该为该行使用的视图类型。


当然,您通常不会直接使用AdapterView和Adapter,而是使用或派生自它们的一个子类。Adapter的子类可以添加额外的功能,改变如何获得不同行的自定义布局。由于给定行所使用的视图是由适配器驱动的,因此诀窍是让适配器为给定行返回所需的视图。如何做到这一点取决于特定的适配器。

例如,要使用ArrayAdapter,

重写getView()来填充、填充并返回给定位置所需的视图。getView()方法包括通过convertView参数重用视图的机会。

但是要使用CursorAdapter的衍生物,

覆盖newView()来膨胀,填充,并返回当前游标状态所需的视图(即当前“行”)[你还需要覆盖bindView,以便小部件可以重用视图]

然而,要使用SimpleCursorAdapter,

定义一个SimpleCursorAdapter。使用setViewValue()方法对给定行(当前游标状态)和数据“列”进行膨胀、填充并返回所需的视图。该方法可以只定义“特殊”视图,并对“普通”绑定遵循SimpleCursorAdapter的标准行为。

查找您最终使用的适配器类型的特定示例/教程。