I am getting an IndexOutOfBoundsException, that I need some help with.
Here is the error in my stack trace
FATAL EXCEPTION: main
Process: com.guhring.vending, PID: 2210
java.lang.IndexOutOfBoundsException: Invalid index 4, size is 4
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.guhring.vending.adapters.ReportAdapter.getView(ReportAdapter.java:112)
at android.widget.AbsListView.obtainView(AbsListView.java:2346)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1280)
at android.widget.ListView.onMeasure(ListView.java:1188)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
I know why the exception is happening, it is because in my JSON File, the machinereports Array has a different amount of items, if you look below, the first item has 4 items and the second item has 6,
{
"id" : 1,
"reports": [
{
"id": "1",
"title": "For Reorder",
"subtitle": "Report Name",
"date": "Monday, Aug 08, 2016",
"machinereports": [
{
"name": "Reorder List",
"count": "9"
},
{
"name": "Reorder List Critical",
"count": "9"
}
]
},
{
"id": "2",
"title": "For Stock",
"subtitle": "Report Name",
"date": "Monday, Aug 08, 2016",
"machinereports": [
{
"name": "Article List",
"count": "531"
},
{
"name": "Articles Out For More Than 7 Days",
"count": "1"
},
{
"name": "Stock Report",
"count": "559"
}
]
}
]
}
Here is my main class Activity and Report Class
public class MachineReportsActivity extends AppCompatActivity {
private ReportAdapter adapter;
private ListView mListView;
private ArrayList<Report> reportList;
private String id;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
setContentView(R.layout.machinereports);
Intent i = getIntent();
id = i.getStringExtra("id");
mListView = (ListView) findViewById(R.id.machine_report_list_view);
reportList = Report.getReportsFromFile("reports.json", this);
adapter = new ReportAdapter(this, reportList);
if (mListView != null) {
mListView.setAdapter(adapter);
}
}
}
public class Report {
public String id;
public String title;
public String subtitle;
public String date;
public ArrayList<String> machinereports = new ArrayList<>();
public static ArrayList<Report> getReportsFromFile(String filename, Context context) {
final ArrayList<Report> reportList = new ArrayList<>();
try {
// Load Data
String jsonStr = loadJsonFromAsset("reports.json", context);
JSONObject jsonOne = new JSONObject(jsonStr);
JSONArray reports = jsonOne.getJSONArray("reports");
// Get Report objects from data
for(int i = 0; i < reports.length(); i++) {
Report report = new Report();
report.id = reports.getJSONObject(i).getString("id");
report.title = reports.getJSONObject(i).getString("title");
report.subtitle = reports.getJSONObject(i).getString("subtitle");
report.date = reports.getJSONObject(i).getString("date");
// Get inner array listOrReports
/* JSONArray rList = jsonOne.getJSONArray("machinereports");*/
JSONArray rList = reports.getJSONObject(i).getJSONArray("machinereports");
for(int j = 0; j < rList.length(); j++) {
JSONObject jsonTwo = rList.getJSONObject(j);
report.machinereports.add(jsonTwo.getString("name"));
report.machinereports.add(jsonTwo.getString("count"));
}
reportList.add(report);
}
} catch (JSONException e) {
e.printStackTrace();
}
return reportList;
}
private static String loadJsonFromAsset(String filename, Context context) {
String json = null;
try {
InputStream is = context.getAssets().open(filename);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
}
catch (java.io.IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
}
My custom Adapter is set up like this
public class ReportAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflater;
private ArrayList<Report> mDataSource;
private ArrayList<Report> arrayList;
public ReportAdapter(Context context, ArrayList<Report> items) {
mContext = context;
mDataSource = items;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
arrayList = new ArrayList<Report>();
arrayList.addAll(mDataSource);
}
// Implement a ViewHolder Class which stores each of the row's subviews,
// and in turn is stored inside the tag field of the layout
private static class ViewHolder {
public TextView titleTextView;
public TextView subTitleTextView;
public TextView dateTextView;
public TextView reportOneTextView;
public TextView reportTwoTextView;
public TextView reportThreeTextView;
public TextView reportFourTextView;
public TextView reportFiveTextView;
public TextView reportSixTextView;
}
@Override
public int getCount() {
return mDataSource.size();
}
@Override
public Object getItem(int position) {
return mDataSource.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = mInflater.inflate(R.layout.list_item_machine_reports, parent, false);
holder = new ViewHolder();
holder.titleTextView = (TextView) convertView.findViewById(R.id.reports_list_title);
holder.subTitleTextView = (TextView) convertView.findViewById(R.id.reports_list_subtitle);
holder.dateTextView = (TextView) convertView.findViewById(R.id.reports_list_date);
holder.reportOneTextView = (TextView) convertView.findViewById(R.id.reports_list_reportName);
holder.reportTwoTextView = (TextView) convertView.findViewById(R.id.reports_list_reportCount);
holder.reportThreeTextView = (TextView) convertView.findViewById(R.id.reports_list_reportName02);
holder.reportFourTextView = (TextView) convertView.findViewById(R.id.reports_list_reportCount02);
holder.reportFiveTextView = (TextView) convertView.findViewById(R.id.reports_list_reportName03);
holder.reportSixTextView = (TextView) convertView.findViewById(R.id.reports_list_reportCount03);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
TextView titleTextView = holder.titleTextView;
TextView subTitleTextView = holder.subTitleTextView;
TextView dateTextView = holder.dateTextView;
TextView reportOneTextView = holder.reportOneTextView;
TextView reportTwoTextView = holder.reportTwoTextView;
TextView reportThreeTextView = holder.reportThreeTextView;
TextView reportFourTextView = holder.reportFourTextView;
TextView reportFiveTextView = holder.reportFiveTextView;
TextView reportSixTextView = holder.reportSixTextView;
Report report = (Report) getItem(position);
titleTextView.setText(report.title);
subTitleTextView.setText(report.subtitle);
dateTextView.setText(report.date);
reportOneTextView.setText(report.machinereports.get(0));
reportTwoTextView.setText(report.machinereports.get(1));
reportThreeTextView.setText(report.machinereports.get(2));
reportFourTextView.setText(report.machinereports.get(3));
reportFiveTextView.setText(report.machinereports.get(4));
reportSixTextView.setText(report.machinereports.get(5));
return convertView;
}
}
And this is my list item view, In the view I want to populate two of the texviews based on the number of machinereport items returned from the json object, but as you can see, the way I have it set up, it is not allowing me to. I have to write n number of instances of the RelativeLayout and supply the data, but the machinereport data count is variable.
<RelativeLayout
android:id="@+id/RelativeLayout03"
android:layout_width="300dp"
android:layout_height="30dp"
android:background="#ffffff"
android:orientation="horizontal"
android:layout_marginTop="22dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="20dp"
android:layout_marginStart="20dp">
<TextView
android:id="@+id/reports_list_reportName"
android:layout_width="230dp"
android:layout_height="wrap_content"
android:textSize="12sp"
tools:text="ReportName"
android:textStyle="bold"
android:paddingLeft="15dp"
android:textColor="#000000"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/imageView"
android:layout_toEndOf="@+id/imageView" />
<TextView
android:id="@+id/reports_list_reportCount"
android:layout_width="25dp"
android:layout_height="wrap_content"
android:textSize="15sp"
tools:text=""
android:textStyle="bold"
android:textColor="#000000"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:layout_alignTop="@+id/reports_list_reportName"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<ImageView
android:layout_width="20dp"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:layout_alignTop="@+id/reports_list_reportName"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_alignBottom="@+id/reports_list_reportName"
android:src="@drawable/file" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/RelativeLayout04"
android:layout_width="300dp"
android:layout_height="30dp"
android:background="#ffffff"
android:orientation="horizontal"
android:layout_marginTop="20dp"
android:layout_below="@+id/RelativeLayout03"
android:layout_alignLeft="@+id/RelativeLayout03"
android:layout_alignStart="@+id/RelativeLayout03">
<TextView
android:id="@+id/reports_list_reportName02"
android:layout_width="230dp"
android:layout_height="wrap_content"
android:textSize="12sp"
tools:text="ReportName"
android:textStyle="bold|normal"
android:paddingLeft="15dp"
android:textColor="#000000"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/imageView2" />
<TextView
android:id="@+id/reports_list_reportCount02"
android:layout_width="25dp"
android:layout_height="wrap_content"
android:textSize="15sp"
tools:text=""
android:textStyle="bold"
android:textColor="#000000"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:layout_alignTop="@+id/reports_list_reportName02"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<ImageView
android:layout_width="20dp"
android:layout_height="wrap_content"
android:id="@+id/imageView2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:src="@drawable/file"
android:layout_alignTop="@+id/reports_list_reportName02"
android:layout_alignBottom="@+id/reports_list_reportName02" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/RelativeLayout05"
android:layout_width="300dp"
android:layout_height="30dp"
android:background="#ffffff"
android:orientation="horizontal"
android:layout_marginTop="20dp"
android:layout_below="@+id/RelativeLayout04"
android:layout_alignLeft="@+id/RelativeLayout04"
android:layout_alignStart="@+id/RelativeLayout04">
<TextView
android:id="@+id/reports_list_reportName03"
android:layout_width="230dp"
android:layout_height="wrap_content"
android:textSize="12sp"
tools:text="ReportName"
android:textStyle="bold|normal"
android:paddingLeft="15dp"
android:textColor="#000000"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/imageView6"
android:layout_toEndOf="@+id/imageView6" />
<TextView
android:id="@+id/reports_list_reportCount03"
android:layout_width="25dp"
android:layout_height="wrap_content"
android:textSize="15sp"
tools:text=""
android:textStyle="bold"
android:textColor="#000000"
android:layout_alignTop="@+id/reports_list_reportName03"
android:layout_toRightOf="@+id/reports_list_reportName03"
android:layout_toEndOf="@+id/reports_list_reportName03"
android:layout_marginLeft="7dp"
android:layout_marginStart="7dp" />
<ImageView
android:layout_width="20dp"
android:layout_height="wrap_content"
android:id="@+id/imageView6"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:src="@drawable/file"
android:layout_alignTop="@+id/reports_list_reportName03"
android:layout_alignBottom="@+id/reports_list_reportName03" />
</RelativeLayout>