我有一个多态实体列表,例如List<Person>
,其中一个人可以是员工,经理,士兵,皇室等......我想在Android列表视图中显示人员列表每种类型的人都有不同的行模板和不同的数据。
显示不同类型的不同行的正确方法是什么?
两个糟糕的(?)解决方案:
在getView
类中放置一个抽象的Person
方法,以便每个不同的人都可以通过多态创建正确的视图。 - &GT;这将混合模型和MVC的视图 - 即。如果我想要在不同的屏幕上显示列表(例如表格视图),那么它将会中断。
将模型到视图逻辑放在适配器内(继承自ArrayAdapter<Person>
)。例如,在getView
内,我可以检查此人的getClass()
并相应地填写正确的视图。 - &GT;这种方法将以if-else语句的长链结束,每个人类型一个,并且在添加新类型的人时需要扩展 - 通常在面向对象的观点中有一些不良代码的味道。这是“How to create list with different elements and actions?”
是否有比上述(2)更好的解决方案?
答案 0 :(得分:2)
我个人会选择与你的第二个解决方案类似的东西。我可能在Person
类中包含一个抽象方法来识别人的类型,因此您可以使用getClass()
对Person
对象getView()
进行检查。调用。
在自定义适配器中,扩展BaseAdapter
并确保getViewTypeCount()
返回数据集中不同类型人员的数量,并getItemViewType(int position)
返回正确的标识符在数据集中的位置。
这个问题有很多关于这个问题的有用信息:
getViewTypeCount and getItemViewType methods of ArrayAdapter
答案 1 :(得分:1)
创建自己的ListAdapter,它从BaseAdapter扩展,如下所示
public class YourListAdapter extends BaseAdapter implements Filterable {
...
}
覆盖getViewTypeCount()和getItemViewType()
@Override
public int getViewTypeCount() {
return 2;//count of types
}
@Override
public int getItemViewType(int position) {
return YourPersonList.get(position).getMyViewType();
}
并在getView(..)
中int type = getItemViewType(position);
switch(type){
case 0:
//set the view to your layout
break;
case 1:
//set the view to another layout
break;
}
或多或少类似......
//编辑:查看来自michell https://stackoverflow.com/a/17152430/1847899
的帖子答案 2 :(得分:1)
您可以在适配器中覆盖两种方法,使这更容易。他们是:
@Override
public int getViewTypeCount(){
return viewTypeCount;
}
@Override
public int getItemViewType(int pos){
if (getItem(pos).type == employee)
return VIEW_TYPE_EMPLOYEE;
else if (getItem(pos).type == manager)
return VIEW_TYPE_MANAGER;
}
使用上面的方法,您仍然需要做一些工作,例如当视图需要膨胀时,您可能必须从getView内部调用getItemViewType(position),但是当您获得已被回收的视图时,适配器应根据行位置为您提供正确的类型。