Почему рецепты поощряют переопределение getItemViewType и getViewTypeCount, когда это не кажется необходимым?

Я был работая с учебниками по программированию для Android от Commonsware и в учебнике 5, дополнительный балл 2, задача состоит в том, чтобы использовать несколько макетов для отображения строк в ListView в зависимости от «имени типа» объекта (атрибут «тип» ресторана, который является String). Таким образом, предлагается переопределить getItemViewTypeи getViewTypeCountв пользовательском ArrayAdapter. Кроме того, документы Androidи другие онлайн-рецепты] или сообщения в блогепредполагают то же самое.

В этой ситуации следование этому рецепту и переопределение этих двух методов работает нормально, но приводит к избыточной логике, основанной на проверке значения этого атрибута «тип» ресторана. пример (обратите внимание, что этот адаптер является внутренним классом и остальные aurants— это ArrayList объектов Restaurant, объявленных как член внешней Activity):

class RestaurantsAdapter extends ArrayAdapter {

  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/else в getItemViewTypeи switchв getView). Итак, я изменил свою реализацию на следующую:

class RestaurantsAdapter extends ArrayAdapter {

  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, удаляет избыточную логику, немного уменьшает связь кода с количеством макетов и не требует переопределения getViewTypeCountи getItemViewType.

Мой вопрос: зачем переопределять эти два метода, если в этом нет необходимости?

7
задан Community 23 May 2017 в 11:45
поделиться