ArrayIndexOutOfBoundsException зі спеціальним адаптером Android для декількох переглядів у ListView


185

Я намагаюся створити спеціальний адаптер для мого ListView, оскільки кожен елемент у списку може мати інший вигляд (посилання, тумблер або радіогрупа), але коли я намагаюся запустити Діяльність, яка використовує ListView, я отримую помилку та додаток зупиняється. Додаток орієнтовано на платформу Android 1.6.

Код:

public class MenuListAdapter extends BaseAdapter {
 private static final String LOG_KEY = MenuListAdapter.class.getSimpleName();

 protected List<MenuItem> list;
 protected Context ctx;
 protected LayoutInflater inflater;

 public MenuListAdapter(Context context, List<MenuItem> objects) {
  this.list = objects;
  this.ctx = context;
  this.inflater = (LayoutInflater)this.ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  Log.i(LOG_KEY, "Position: " + position + "; convertView = " + convertView + "; parent=" + parent);
  MenuItem item = list.get(position);
  Log.i(LOG_KEY, "Item=" + item );

        if (convertView == null)  {
            convertView = this.inflater.inflate(item.getLayout(), null);
        }

        return convertView;
 }

 @Override
 public boolean areAllItemsEnabled() {
  return false;
 }

 @Override
 public boolean isEnabled(int position) {
  return true;
 }

 @Override
 public int getCount() {
  return this.list.size();
 }

 @Override
 public MenuItem getItem(int position) {
  return this.list.get(position);
 }

 @Override
 public long getItemId(int position) {
  return position;
 }

 @Override
 public int getItemViewType(int position) {
  Log.i(LOG_KEY, "getItemViewType: " + this.list.get(position).getLayout());
  return this.list.get(position).getLayout();
 }

 @Override
 public int getViewTypeCount() {
  Log.i(LOG_KEY, "getViewTypeCount: " + this.list.size());
  return this.list.size();
 }

}

Отримана помилка:

    java.lang.ArrayIndexOutOfBoundsException
  at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:3523)
  at android.widget.ListView.measureHeightOfChildren(ListView.java:1158)
  at android.widget.ListView.onMeasure(ListView.java:1060)
  at android.view.View.measure(View.java:7703)

Я знаю, що програма повертається з getViewі все здається в порядку.

Будь-які ідеї щодо того, що це може спричинити, будуть вдячні.

Дякую,

-Дан


Привіт Ден, ти впевнений, що getCount має загальну кількість елементів, які відображатимуться у твоєму ListView ??? public int getCount () {return this.list.size (); }
Хорхесіс

4
Вони не змогли придумати менш описові повідомлення про помилку ...
JoeyJ

Відповіді:


515

Тип перегляду предмета, з якого ви повертаєтесь

getItemViewType()є >= getViewTypeCount().


24
Цей неприємний. Немає можливості налагодити це. Велике спасибі, Ромен Гай за пояснення цього.
Яр

113
Інша справа, що ViewType повинен починатися з 0.
HelmiB

16
На сьогодні ви отримали 38 пропозицій щодо відповіді, тому це може бути ідеальною відповіддю, але будь ласка, додайте ще трохи тексту для пояснення проблеми та способів її вирішення. Тому що я все ще не можу багато що з цього зрозуміти.
Chirag Patel

15
Для тих, хто наткнувся, ViewType повинен повернути нульовий індекс. наприклад (0, 1, 2 ...). у моєму випадку я намагався повторно використати R.layout ... для ViewType. Я гадаю, що внутрішньо значення ViewType використовується як індекс для пулу переробки, а не як ключове.
Самуїл

2
Дякуємо, що пояснили цю помилку на відміну від розробників Android, які, як завжди, не могли потурбуватися згадувати цей життєвий тит у своїй документації.
WKS

17

Прийнята відповідь правильна. Ось що я роблю, щоб уникнути проблеми:

public enum FoodRowType {
    ONLY_ELEM,
    FIRST_ELEM,
    MID_ELEM,
    LAST_ELEM
}

@Override
public int getViewTypeCount() {
    return FoodRowType.values().length;
}

@Override
public int getItemViewType(int position) {
    return rows.get(position).getViewType();  //returns one of the above types
}

Могло б бути приємно, тільки якби getItemViewTypeне повернутись до int
dVaffection

0

Проблема виникає, коли значення getItemType неправильне. Це значення повинно бути цілим числом і має бути від 0 до getViewTypeCount () - 1.


-3

Причина, швидше за все, тому, що метод getItemViewType повертає неправильні значення! Кожен рядок у перегляді списку - це один перегляд. Під час прокрутки getItemViewType досягає більше, ніж кількість переглядів.

Що робити? Як уникнути проблеми?

Спочатку визначте подання (рядок) у вашому перегляді списку, який показано першим. Під час прокрутки використовується рівняння модуля

    @Override
    public int getItemViewType(int position) {
        return choseType(position);//function to use modular equation
    }
    @Override
    public int getViewTypeCount() {
        return 10;
    }

У цьому прикладі є десять подань (10 ряд).

private  int choseType(int position){
    if(position%10==0)
        return 0;
    else if(position%10==1)
        return 1;
    else if(position%10==2)
        return 2;
    else if(position%10==3)
        return 3;
    else if(position%10==4)
        return 4;
    else if(position%10==5)
        return 5;
    else if(position%10==6)
        return 6;
    else if(position%10==7)
        return 7;
    else if(position%10==8)
        return 8;
    else
        return 9;


}

Важливо

Деякі користувачі згадували інше питання про stackoverflow цього методу

громадський ІНТ getViewTypeCount () і суспільне ІНТ getItemViewType (ціле положення) виправлення як Tooglebutton автоматично включити перевірку стану істинні на scrooling .. це велике неправильно Якщо ви не хочете , автоматичний enbale на приладах типу СПІРАЛЬНОГО вобще

toogleButton.setChecked(false);

на метод перегляду getView.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.