Android ListView с несколькими макетами

Мне нужно показать список с разными типами представлений. Поэтому мне нужно определить ListView с адаптером, где мне нужно раздуть несколько представлений. Я рассмотрел приведенный пример, но проблема в том, что мой список не симметричен, как в примере, где заголовок повторяется каждый раз после 4 элементов. Итак, я столкнулся с проблемой повторного использования элементов в getView().

 public View getView(int position, View convertView, ViewGroup parent) {   
    int type = getItemViewType(position);
    if (convertView == null) {
        holder = new ViewHolder();
        switch (type) {
             case TYPE_1:
             convertView = mInflater.inflate(R.layout.item1, null);
             .......
             break;

             case TYPE_2:
             convertView = mInflater.inflate(R.layout.item2, null);
             .......
             break;
        }
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder)convertView.getTag();
    }
    ............
    ............
}

Теперь, если convertView не равен null, но тип элемента, для которого он ранее использовался, был другим, тогда макет не будет совпадать с таким же. Как этот код будет решать эту проблему?


person dev_android    schedule 06.04.2015    source источник
comment
Не проверяйте нулевое условие для convertview, которое всегда будет раздувать макет элемента.   -  person Pankaj    schedule 06.04.2015
comment
нужно сделать 2 ViewHolder для раскладок item1 и item2, а в else где convertView !=null нужно проверить type и привести к ViewHolder1 или ViewHolder2... как думаете?   -  person Yazan    schedule 06.04.2015
comment
Если элементы списка имеют несимметричный макет, вы можете иметь один элемент списка xml со всеми необходимыми элементами, а в методе getView на основе типа вы можете установить видимость показать/скрыть/исчезнуть.   -  person    schedule 06.04.2015
comment
Предположим, что 1-й элемент был типа 1 (имеющий макет_1), и он будет повторно использоваться в 8-м элементе, который имеет тип 2 (имеющий макет_2). Теперь, если тег 1-го элемента (который на самом деле является объектом ViewHolder1) приведет его к ViewHolder2, он будет работать? Кроме того, макет также будет другим. Как это будет работать?   -  person dev_android    schedule 06.04.2015


Ответы (3)


Вы можете посмотреть этот пример адаптера. Метод getViewTypeCount возвращает строку другого типа. getItemViewType, если позиция равна 0, раздувает макет первой строки, иначе раздувает другой макет строки. Вы можете настроить этот пример кода.

    import java.util.List;
    import android.app.Activity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;

    /**
     * Created by MustafaS on 9.2.2015.
     */
    public class CustomArrayAdapter extends ArrayAdapter<YourModel> {

       @Override
       public int getItemViewType(int position) {

          if (position == 0) {
             return 0;
          }
          else {
             return 1;
          }
       }

       @Override
       public int getViewTypeCount() {
          return 2;
       }

       @Override
       public View getView(int position, View convertView, ViewGroup parent) {
          int type = getItemViewType(position);
          if (type == 0) {
             if (convertView == null) {
                convertView = LayoutInflater.from(activity).inflate(R.layout.listview_first_row, parent, false);
                viewHolderFirst = new ViewHolderFirst();
                convertView.setTag(viewHolderFirst);
             }
             else {
                viewHolderFirst = (ViewHolderFirst) convertView.getTag();
             }

          }
          else {
             if (convertView == null) {
                convertView = LayoutInflater.from(activity).inflate(R.layout.listview_other_row, parent, false);
                viewHolder = new ViewHolder();

             }
             else {
                viewHolder = (ViewHolder) convertView.getTag();
             }
          }
          return convertView;
       }

       protected class ViewHolderFirst {
          private RunnableViewPager pager;
          private CircleIndicator   indicator;
       }

       protected class ViewHolder {
          private ImageView imageviewRestaurant;
          private TextView  textviewRestaurantName;
          private TextView  textviewType;
          private TextView  textviewPrice;
          private TextView  textviewDistance;
          private ImageView imageviewCall;
          private ImageView imageviewCalendar;
       }
    }
person msevgi    schedule 06.04.2015
comment
Предположим, что 1-й элемент был типа 1 (имеющий макет_1), и он будет повторно использоваться в 8-м элементе, который имеет тип 2 (имеющий макет_2). Теперь, если тег 1-го элемента (который на самом деле является объектом ViewHolderFirst) приведет его к ViewHolder, он будет работать? Кроме того, макет также будет другим. Как это будет работать? - person dev_android; 06.04.2015
comment
если ваша первая строка много отличается от другой строки, вы должны сделать это. Но если ваши строки похожи, вы можете использовать одну строку xml и один видоискатель. - person msevgi; 06.04.2015
comment
layout_1 и layout_2 разные. Как его можно повторно использовать для типа 2, который ранее использовался для типа 1? - person dev_android; 06.04.2015

Вы можете сделать это, переопределив методы getViewCount() и getItemViewType(int position).

В первом вы просто возвращаете количество различных просмотров, которые у вас есть.

Во втором вы возвращаете уникальный идентификатор для каждого отдельного представления.

В своем методе getView() вы проверяете тип представления и надуваете для него правильный макет.

Дополнительная информация по этой теме: Android ListView с разными макетами для каждой строки

Android ListView с разными макетами для каждой строки

person rubengees    schedule 06.04.2015

Это то, что вам нужно использовать, когда вы используете разные типы представлений внутри ListView или RecyclerView: -

getItemViewType() and getViewTypeCount()

Сначала вам нужно использовать getViewTypeCount() и вернуть количество уникальных представлений, которые вам нужны внутри вашего списка. Затем переопределите getItemViewType() и верните тип представления на основе любого условия, которое вы хотите, чтобы ваши представления изменялись внутри ListView.

Надеюсь, это поможет.

person Varundroid    schedule 06.04.2015