私は Commonsware Android Programming Tutorials に取り組んでおり、チュートリアル 5 の追加クレジット 2 では、オブジェクトの「タイプ名」(レストランの「タイプ」属性) に応じて、ListView に行を表示するために複数のレイアウトを使用することが課題です。 、これは文字列です)。そのため、カスタム ArrayAdapter でオーバーライドすることをgetItemViewType
おgetViewTypeCount
勧めします。さらに、Android のドキュメントや他のオンライン レシピやブログ投稿でも同じことが示唆されています。
この状況では、このレシピに従ってこれら 2 つのメソッドをオーバーライドすると問題なく動作しますが、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;
}
}
私を悩ませているのは、ロジックの重複です( if/elsegetItemViewType
とswitch
in 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;
}
}
getViewTypeCount
これにより、3 つの xml レイアウトのうちの 1 つを動的にロードするという目標が達成され、冗長なロジックが削除され、コードとレイアウトの数との結合がわずかに減少し、とをオーバーライドする必要がなくなりますgetItemViewType
。
私の質問は、これらの 2 つのメソッドを上書きする必要がないのに、なぜこれらの 2 つのメソッドを上書きする必要があるのですか?