ArrayIndexOutOfBoundsException с пользовательским адаптером Android для нескольких представлений в ListView
Я пытаюсь создать пользовательский адаптер для моего 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
и все вроде в порядок.
любые идеи о том, что может быть причиной этого будут оценены.
спасибо,
-Дэн
4 ответа:
принятый ответ правильный. Вот что я делаю, чтобы избежать этой проблемы:
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 }
проблема возникает, когда getItemType значение неверно. Это значение должно быть целым числом и должно быть от 0 до getViewTypeCount () -1.
причина, скорее всего, потому, что метод getItemViewType возвращает неправильные значения! Каждая строка в listview-это одно представление. В то время как scrooling getItemViewType достигает больше, чем количество просмотров.
что делать? Как избежать проблемы?
сначала определите вид (строку) в вашем listview, который отображается первым.При прокрутке используйте уравнение модулятора
@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 этот метод
public int getViewTypeCount () и public int getItemViewType (int position) исправить как Tooglebutton автоматически включить проверку состояния true на скрулинг..это большая ошибка .Если вы не хотите автоматического enbale на Скрул просто сделать
toogleButton.setChecked(false);
при переопределении getView метод.