我遇到了关于IndexOutOfBoundsException的错误

时间:2016-03-05 16:17:48

标签: android json listview indexoutofboundsexception

我有一个Json数据,我想在listView中显示信息,所以我将它们解析为ArrayList<String>,然后添加到适配器。

{
  "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天所以有人帮我吗?非常感谢你

2 个答案:

答案 0 :(得分:0)

使用时

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

你基本上告诉适配器为 mData 列表中的每个项目调用getView()方法。 getView()方法中的position参数对应于mData列表中的条目。然后使用相同的位置参数从三个其他列表中获取数据,这些列表可能与 mData 列表的大小不同,因此其中一个列表上的get(position)调用之一将抛出你看到的例外。如果您在适配器的第106行的Android Studio中使用调试器,则可以轻松调试。

答案 1 :(得分:0)

在适配器中,数据的大小由getCount确定,您可以这样定义。

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

这意味着getView中的位置范围为getCount返回的值的0。

但是,您似乎有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个单独的String Arraylists,因为该数据似乎属于单个Object,如果您想要一个合适的自定义适配器,您可以给它一个Object类型列表(例如,从Gson解析)而不是对象的单个部分