ArrayIndexOutOfBoundException với Bộ điều hợp Android tùy chỉnh cho nhiều chế độ xem trong ListView


185

Tôi đang cố gắng tạo Bộ điều hợp tùy chỉnh cho ListView của mình vì mỗi mục trong danh sách có thể có chế độ xem khác nhau (liên kết, chuyển đổi hoặc nhóm radio), nhưng khi tôi thử chạy Hoạt động sử dụng ListView, tôi gặp lỗi và ứng dụng dừng lại. Ứng dụng này được nhắm mục tiêu cho nền tảng Android 1.6.

Mật mã:

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

}

Lỗi tôi nhận được:

    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)

Tôi biết rằng ứng dụng đang trở lại getViewvà mọi thứ dường như theo thứ tự.

Bất kỳ ý tưởng về những gì có thể gây ra điều này sẽ được đánh giá cao.

Cảm ơn,

-Dan


Xin chào, bạn có chắc chắn getCount có tổng số phần tử được hiển thị trên ListView của bạn không ??? công khai int getCount () {return this.list.size (); }
Jorgesys

4
Họ không thể đưa ra một thông báo lỗi ít mô tả hơn ...
JoeyJ

Câu trả lời:


515

Kiểu xem mục bạn đang quay lại từ

getItemViewType()>= getViewTypeCount().


24
Điều này là khó chịu. Không có cách nào để gỡ lỗi nó. Cảm ơn rất nhiều, Romain Guy đã giải thích nó.
Yar

113
một điều nữa là, ViewType phải bắt đầu từ 0.
HelmiB

16
Bạn đã nhận được 38 câu trả lời cho câu trả lời cho đến bây giờ vì vậy đây có thể là một câu trả lời hoàn hảo, nhưng vui lòng thêm một số văn bản để giải thích vấn đề và cách giải quyết nó .. vì tôi vẫn không thể hiểu nhiều về điều này.
Chirag Patel

15
Đối với những người bị bối rối, ViewType phải trả về chỉ số dựa trên số không. ví dụ: (0, 1, 2 ...). trong trường hợp của tôi, tôi đã cố gắng sử dụng lại R.layout ... cho ViewType. Tôi đoán bên trong giá trị của ViewType đang được sử dụng làm chỉ mục cho nhóm tái chế chứ không phải là khóa.
Samuel

2
Cảm ơn bạn đã giải thích lỗi này không giống như các nhà phát triển Android, như thường lệ, không thể bận tâm khi đề cập đến tiêu chuẩn quan trọng này trong tài liệu của họ.
WKS

17

Câu trả lời được chấp nhận là chính xác. Đây là những gì tôi đang làm để tránh vấn đề:

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
}

Chỉ có thể tốt đẹp nếu getItemViewTypekhông trở về int
dVaffection

0

Vấn đề xảy ra khi giá trị getItemType sai. Giá trị này phải là số nguyên và phải từ 0 đến getViewTypeCount () - 1.


-3

Lý do, rất có thể là do phương thức getItemViewType đang trả về các giá trị sai! Mỗi hàng trong listview là một View. Trong khi scrooling getItemViewType đạt nhiều hơn số lượng của View.

Phải làm sao Làm thế nào để tránh vấn đề?

Đầu tiên xác định chế độ xem (hàng) trong chế độ xem danh sách của bạn được hiển thị đầu tiên. Trong khi đó, cuộn sử dụng phương trình điều biến

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

Trong ví dụ này có mười khung nhìn (10 hàng).

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;


}

Quan trọng

Một số người dùng đã đề cập đến một câu hỏi khác về stackoverflow phương thức đó

sửa lỗi int int getViewTypeCount () và public int getItemViewType (int location) như Tooglebutton tự động kích hoạt kiểm tra trạng thái đúng khi scrooling .. đó là sai lớn . Nếu bạn không muốn tự động enbale trên scrool

toogleButton.setChecked(false);

trên phương thức ghi đè getView.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.