yba*_*kos 7 android android-arrayadapter commonsware android-view
我一直在使用Commonsware Android编程教程和教程5,额外的功劳2,挑战是使用多个布局在ListView中显示行,具体取决于对象的"类型名称"(餐厅的"类型"属性,这是一个字符串).因此,它表明压倒一切getItemViewType,并getViewTypeCount在自定义ArrayAdapter.此外,Android文档和其他在线食谱或博客文章也提出了相同的建议.
在这种情况下,遵循此配方并覆盖这两种方法可以正常工作,但会导致基于检查该Restaurant"type"属性值的冗余逻辑.例如(请注意,此适配器是一个内部类,并且restaurants是声明为外部Activity成员的Restaurant对象的ArrayList):
class RestaurantsAdapter extends ArrayAdapter<Restaurant> {
private static final int ROW_TYPE_DELIVERY = 0;
private static final int ROW_TYPE_TAKE_OUT = 1;
private static final int ROW_TYPE_SIT_DOWN = 2;
RestaurantsAdapter() {
super(LunchListActivity.this, android.R.layout.simple_list_item_1, restaurants);
}
public int getViewTypeCount() {
return 3;
}
public int getItemViewType(int position) {
String type = restaurants.get(position).getType();
if (type == "delivery") {
return ROW_TYPE_DELIVERY;
} else if (type == "take_out") {
return ROW_TYPE_TAKE_OUT;
} else {
return ROW_TYPE_SIT_DOWN;
}
}
// Sets the icon, name and address of the Restaurant for the view.
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
RestaurantHolder viewHolder;
if (row == null) {
LayoutInflater inflater = getLayoutInflater();
switch (getItemViewType(position)) {
case ROW_TYPE_DELIVERY:
row = inflater.inflate(R.layout.row_delivery, null);
break;
case ROW_TYPE_TAKE_OUT:
row = inflater.inflate(R.layout.row_take_out, null);
break;
default:
row = inflater.inflate(R.layout.row_sit_down, null);
break;
}
viewHolder = new RestaurantHolder(row);
row.setTag(viewHolder);
} else {
viewHolder = (RestaurantHolder)row.getTag();
}
viewHolder.populateFrom(restaurants.get(position));
return row;
}
}
Run Code Online (Sandbox Code Playgroud)
错误的是重复逻辑(if/else in getItemViewType和switchin getView).所以,我将实现改为以下内容:
class RestaurantsAdapter extends ArrayAdapter<Restaurant> {
RestaurantsAdapter() {
super(LunchListActivity.this, android.R.layout.simple_list_item_1, restaurants);
}
// Sets the icon, name and address of the Restaurant for the view.
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
RestaurantHolder viewHolder;
if (row == null) {
LayoutInflater inflater = getLayoutInflater();
if (restaurants.get(position).getType() == "delivery") {
row = inflater.inflate(R.layout.row_delivery, null);
} else if (restaurants.get(position).getType() == "take_out") {
row = inflater.inflate(R.layout.row_take_out, null);
} else {
row = inflater.inflate(R.layout.row_sit_down, null);
}
viewHolder = new RestaurantHolder(row);
row.setTag(viewHolder);
} else {
viewHolder = (RestaurantHolder)row.getTag();
}
viewHolder.populateFrom(restaurants.get(position));
return row;
}
}
Run Code Online (Sandbox Code Playgroud)
这实现了动态加载三个xml布局之一,删除冗余逻辑,略微减少代码与布局数量的耦合,并且不需要覆盖getViewTypeCount和的目标getItemViewType.
我的问题是:如果不必要,为什么要覆盖这两种方法呢?
Com*_*are 16
如果一个人没有必要,为什么要覆盖这两个方法呢?
添加几十个不同类型的餐馆,并观察当您滚动时,您的行回收会变得混乱,如上所示.
getItemViewType()并getViewTypeCount()确保行回收工作.Android将维护单独的对象池,并且只返回一行以回收具有正确类型的对象.
在您的解决方案中,您可以膨胀R.layout.row_delivery一行,然后在您真正需要一R.layout.row_sit_down排时将其交还给您进行回收.
顺便说一句,不要用inflate(R.layout.row_take_out, null)在AdapterView.要使RelativeLayout规则正确处理,请使用inflate(R.layout.row_take_out, parent, false).
| 归档时间: |
|
| 查看次数: |
3938 次 |
| 最近记录: |