2016-03-05 46 views
0

我有一個Json數據,我想在我的listView中顯示信息,因此我將它們解析爲ArrayList<String>,然後添加到適配器中。我遇到了一些關於IndexOutOfBoundsException的錯誤

{ 
    "areas": [ 
    { 
     "fieldTag": "1", 
     "areaId": 2, 
     "areaName": "No.1", 
     "devices": [ 
     { 
      "cameraName": "A", 
      "busyFields": "null", 
      "freeFields": "No.1,NO,2", 
     },{ 
      "cameraName": "B" 
      "busyFields": "null", 
      "freeFields": "No.3,No.4", 
     } 
     ] 
    } 
    ], 
    "error": 0, 
    "message": "ok" 
} 

我用GSON解析它,我做的數據列表在適配器告訴他們,我的代碼是:

if (mDeviceInfo.getError() == 0) { 
      for (int i = 0; i<mDeviceInfo.getAreas().size();i++){ 
       adapter.addSectionHeaderItem(mDeviceInfo.getAreas().get(i).getAreaName()); 
       for (int k = 0; k<mDeviceInfo.getAreas().get(i).getDevices().size();k++){ 

        adapter.addItem(mDeviceInfo.getAreas().get(i).getDevices().get(k).getCameraName()); 

        mPositionList.add(mDeviceInfo.getAreas().get(i).getDevices().get(k).getPosition()); 
        mFreeFieldsList.add(mDeviceInfo.getAreas().get(i).getDevices().get(k).getFreeFields()); 
        mBusyFieldsList.add(mDeviceInfo.getAreas().get(i).getDevices().get(k).getBusyFields());     
     } 
      } 
      adapter.addMessage(mPosition,mFreeFields,mBusyFields); 
     }else { 
      Toast.makeText(this,"get info failed",Toast.LENGTH_SHORT).show(); 
     } 

,這是我的代碼爲適配器:

public class CameraListAdapter extends BaseAdapter { 

    private static final int TYPE_ITEM = 0; 
    private static final int TYPE_SEPARATOR = 1; 

    private ArrayList<String> mData = new ArrayList<String>(); 
    private ArrayList<String> mPosition = new ArrayList<>(); 
    private ArrayList<String> mFreeFields = new ArrayList<>(); 
    private ArrayList<String> mBusyFields = new ArrayList<>(); 

    private TreeSet<Integer> sectionHeader = new TreeSet<Integer>(); 

    private LayoutInflater mInflater; 

    public CameraListAdapter(Context context) { 
     mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    } 

    public void addItem(final String item) { 
     mData.add(item); 
     notifyDataSetChanged(); 
    } 

    public void addSectionHeaderItem(final String item) { 
     mData.add(item); 
     sectionHeader.add(mData.size() - 1); 
     notifyDataSetChanged(); 
    } 
    public void addMessage(ArrayList<String> position,ArrayList<String> freeFields,ArrayList<String> busyFields){ 
     mPosition = position; 
     mFreeFields = freeFields; 
     mBusyFields = busyFields; 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return sectionHeader.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM; 
    } 

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

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

    @Override 
    public String getItem(int position) { 
     return mData.get(position); 
    } 

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

    @Override 
    public boolean isEnabled(int position) { 
     return getItemViewType(position) != TYPE_SEPARATOR; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder viewHolder = null; 
     int rowType = getItemViewType(position); 

     if (convertView == null) { 
      viewHolder = new ViewHolder(); 
      switch (rowType) { 
       case TYPE_ITEM: 
        convertView = mInflater.inflate(R.layout.cameradetail, null); 
        viewHolder.mCameraName = (TextView) convertView.findViewById(R.id.cameraName); 
        Log.d("CameraListAdapter","position "+position); 
        viewHolder.mCameraName.setText(mData.get(position)); 

        viewHolder.position = (TextView) convertView.findViewById(R.id.cameraposition); 
        viewHolder.position.setText(mPosition.get(position)); 

        viewHolder.busyFields = (TextView) convertView.findViewById(R.id.busyfields); 
        viewHolder.busyFields.setText(mBusyFields.get(position)); 

        viewHolder.freeFields = (TextView) convertView.findViewById(R.id.freefields); 
        viewHolder.freeFields.setText(mFreeFields.get(position)); 

        break; 
       case TYPE_SEPARATOR: 
        convertView = mInflater.inflate(R.layout.cameratag, null); 
        viewHolder.mTag = (TextView) convertView.findViewById(R.id.areaName); 
        viewHolder.mTag.setText(mData.get(position)); 
        break; 
      } 
      convertView.setTag(viewHolder); 
     } else { 
      viewHolder = (ViewHolder) convertView.getTag(); 
     } 
     return convertView; 
    } 

    public static class ViewHolder { 
     public TextView mTag; 
     public TextView mCameraName; 
     public TextView position; 
     public TextView busyFields; 
     public TextView freeFields; 
    } 


} 

但它總是告訴我,

java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2 
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255) 
at java.util.ArrayList.get(ArrayList.java:308) 
at .CameraListAdapter.getView(CameraListAdapter.java:106) 

它打亂了我2天那麼,有沒有人幫我嗎?謝謝你這麼多

+0

什麼是CameraListAdapter的第106行?另外擴展ArrayAdapter可能比BaseAdapter更有意義 –

+0

異常意味着你試圖使用帶有非現有索引的get(index)來訪問arraylist元素(在你的情況下太大)。一些調試可能會幫助你找出錯誤 – 2016-03-05 16:22:51

+0

@ cricket_007哪一行?你的意思是ViewHolder? – PPTing

回答

0

當您使用

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

你基本上告訴適配器要求每一個項目getView()方法你MDATA列表。 getView()方法中的位置參數對應於您的mData列表中的條目。然後,您使用相同的位置參數從其他三個列表中獲取數據,這些列表的大小可能與mData列表的大小不同,因此其中一個get(position)調用將會拋出您看到的異常。如果您在適配器的第106行中使用Android Studio中的調試器,則可以輕鬆調試此代碼。

+0

所以這意味着重寫方法'isEnable()'與'getView()'中使用的位置無關?我重寫isEnable方法,所以mTag無法點擊,但它意味着它的位置仍然存在 – PPTing

+0

不,這意味着你不應該使用一個'ArrayList'的索引(在這種情況下* mData *列表來獲得一個如果你的* mData *列表的大小爲10,那麼'getView()'方法將被調用,值爲10的*位置*參數,你可以像這樣使用該位置:'mFreefields.get( 10)'當你甚至不知道* mFreefields *列表的長度是多少時。 –

0

在適配器中,數據大小由您定義的getCount決定。

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

這意味着位置在getView的範圍是0到由getCount返回的值。

但是,你似乎有4列出了各種大小的,或至少不一樣大小mData

private ArrayList<String> mData = new ArrayList<String>(); 
private ArrayList<String> mPosition = new ArrayList<>(); 
private ArrayList<String> mFreeFields = new ArrayList<>(); 
private ArrayList<String> mBusyFields = new ArrayList<>(); 

我不知道哪一個是造成問題的原因,但是,例如,這將拋出一個異常,如果mPosition不持有相同的數據量mData

viewHolder.position.setText(mPosition.get(position)); 

我建議你不要有4個獨立的小號因爲這些數據似乎與單個對象有關,如果你想要一個適當的自定義適配器,你給它一個你的對象類型列表(例如從Gson解析),而不是一個對象的單個片斷。

相關問題