食谱为什么提倡覆盖getItemViewType和getViewTypeCount时,似乎有必要不?

2019-07-29 02:52发布

我已经通过Commonsware的Android编程教程和教程5,额外的学分2个工作,面临的挑战是使用多个布局根据对象的“类型名称”(餐厅的“类型”属性在ListView中显示行,这是一个字符串)。 因此,它表明压倒一切getItemViewTypegetViewTypeCount在自定义ArrayAdapter。 另外, Android的文档和其他在线食谱或博客文章建议相同。

在这种情况下,下面这几招并覆盖这两种方法工作正常,但导致多余的逻辑基础上检查该餐厅的“类型”属性的值。 例如(注意,这是适配器的内部类和restaurants是声明为外部活动的成员餐厅对象的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;
  }

}

什么错误我是重复的逻辑(如果/其他getItemViewTypeswitchgetView )。 于是,我改变了我实现以下几点:

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;
  }

}

这实现的动态加载的三个XML布局一个目标,删除冗余逻辑,稍微降低的代码耦合布局的数目,并且不需要重写getViewTypeCountgetItemViewType

我的问题是:为何要覆盖这两种方法,如果不就得了?

Answer 1:

为什么要一个覆盖这两种方法,如果不就得了?

加入几十个餐厅,所有不同类型的,并且看着你行回收进入疯狂滚动时,由于上面显示您的实现。

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)



文章来源: Why do recipes promote overriding getItemViewType and getViewTypeCount when it doesn't seem necessary?