PROBLEM
I have created custom ListView which contains custom View, and some textViews per List Item. Everything work as I expect until device orientation change, ListView disappear. I know the issue happen when orientation change activity will recrate. But, I have already save necessary file in application as JSON String format and when activity recreate I found that data was load and run successfully till the end of the code no force close however, listview is not show?
NOTE
I'm sure that my save data is usable because this file is use for prevent fetching data from internet if available and I have test it already, it work!
my custom listview have listview class provide arraylist and adapter class, but I can't provide it here because it too long.
MAIN CLASS
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.schedule);
aq = new AQuery(this);
lvSchedule = (ListView) findViewById(R.id.listView_schedule);
scheduleLvItems = new ArrayList<Schedule_ListView>();
dm = new DataManager(this);
//check available in app data
String scheduleJSON = dm.readFile("scheduleJSON");
if (scheduleJSON != "empty"){
System.out.println(scheduleJSON);
renderData(scheduleJSON);
}
else{
String url = "http://requestURL/getSchedule_v2.php?+" +
"loginId="+yourID+
"&password="+yourPassword+
"&year=2013&semester=2";
aq.ajax(url,String.class, this,"cb1");
}
}
public void cb1(String url, String html, AjaxStatus status){
System.out.println(html);
renderData(html);
}
public void renderData(String jsonString){
try {
List<List<String>> monData = new ArrayList<List<String>>();
List<List<String>> tueData = new ArrayList<List<String>>();
List<List<String>> wedData = new ArrayList<List<String>>();
List<List<String>> thuData = new ArrayList<List<String>>();
List<List<String>> friData = new ArrayList<List<String>>();
List<List<String>> satData = new ArrayList<List<String>>();
List<List<String>> sunData = new ArrayList<List<String>>();
/*Note [Knowledge]
*JSON Symbol {,} = JSONObject
*JSON symbol [,] = JSONArray
*/
//Change JSONString to JSONArray
JSONArray jsonArray_data = new JSONArray(jsonString);
//Set jsonArray_data in global variable for further use
// ((Global_Variable)getApplicationContext()).setJsonSubject(jsonArray_data);
//Save Persistence Json Array in app data for fetch with out internet
dm.writeFile("scheduleJSON",jsonArray_data.toString());
for(int i = 0; i < jsonArray_data.length(); i++){
//Change object to String and stored each JSON item in Variable
JSONObject dataRecord = jsonArray_data.getJSONObject(i);
String yearSemester = dataRecord.getString("YEAR / SEM");
String courseID = dataRecord.getString("COURSE ID");
String courseName = dataRecord.getString("COURSE NAME");
String courseSection = dataRecord.getString("SECTION");
JSONArray courseInfo = dataRecord.getJSONArray("COURSE INFO");
String finalDate = dataRecord.getString("FINAL DATE");
String finalRoom = dataRecord.getString("FINAL ROOM");
String finalTime = dataRecord.getString("FINAL TIME");
String midtermDate = dataRecord.getString("MIDTERM DATE");
String midtermRoom = dataRecord.getString("MIDTERM ROOM");
String midtermTime = dataRecord.getString("MIDTERM TIME");
int subjectColor = getResources().getColor(SUBJECT_COLOR[i]);
for(int ii = 0; ii < courseInfo.length(); ii++){
//Change object to String and stored each JSON item in Variable
JSONObject infoRecord = courseInfo.getJSONObject(ii);
String day = infoRecord.getString("DAY").replace(".","").trim();
String tStart = infoRecord.getString("TIME").replace(" - ","").trim().substring(0,5);
String tStop = infoRecord.getString("TIME").replace(" - ","").trim().substring(5);
String roomStudy = infoRecord.getString("ROOM STUDY");
String instructor = infoRecord.getString("INSTRUCTOR");
List<String> dataRow = new ArrayList<String>();
if (day.contains("Mon")) {
dataRow.add(courseName); //course name
dataRow.add(tStart); //period start
dataRow.add(tStop); //period end
dataRow.add(String.valueOf(subjectColor)); //subject color
dataRow.add(String.valueOf(i)); //subject position in json
monData.add(dataRow);
} else if (day.contains("Tue")) {
dataRow.add(courseName); //course name
dataRow.add(tStart); //period start
dataRow.add(tStop); //period end
dataRow.add(String.valueOf(subjectColor)); //subject color
dataRow.add(String.valueOf(i)); //subject position in json
tueData.add(dataRow);
} else if (day.contains("Wed")) {
dataRow.add(courseName); //course name
dataRow.add(tStart); //period start
dataRow.add(tStop); //period end
dataRow.add(String.valueOf(subjectColor)); //subject color
dataRow.add(String.valueOf(i)); //subject position in json
wedData.add(dataRow);
} else if (day.contains("Thu")) {
dataRow.add(courseName); //course name
dataRow.add(tStart); //period start
dataRow.add(tStop); //period end
dataRow.add(String.valueOf(subjectColor)); //subject color
dataRow.add(String.valueOf(i)); //subject position in json
thuData.add(dataRow);
} else if (day.contains("Fri")) {
dataRow.add(courseName); //course name
dataRow.add(tStart); //period start
dataRow.add(tStop); //period end
dataRow.add(String.valueOf(subjectColor)); //subject color
dataRow.add(String.valueOf(i)); //subject position in json
friData.add(dataRow);
} else if (day.contains("Sat")) {
dataRow.add(courseName); //course name
dataRow.add(tStart); //period start
dataRow.add(tStop); //period end
dataRow.add(String.valueOf(subjectColor)); //subject color
dataRow.add(String.valueOf(i)); //subject position in json
satData.add(dataRow);
} else if (day.contains("Sun")){
dataRow.add(courseName); //course name
dataRow.add(tStart); //period start
dataRow.add(tStop); //period end
dataRow.add(String.valueOf(subjectColor)); //subject color
dataRow.add(String.valueOf(i)); //subject position in json
sunData.add(dataRow);
}
}
}
if(monData.size() != 0){
scheduleLvItems.add(new Schedule_ListView(
R.drawable.monday_mdpi,
monData,
getResources().getInteger(R.integer.COLLAPSED_HEIGHT_1)
));
}
if(tueData.size() != 0){
scheduleLvItems.add(new Schedule_ListView(
R.drawable.tuesday_mdpi,
tueData,
getResources().getInteger(R.integer.COLLAPSED_HEIGHT_1)
));
}
if(wedData.size() != 0){
scheduleLvItems.add(new Schedule_ListView(
R.drawable.wendesday_mdpi,
wedData,
getResources().getInteger(R.integer.COLLAPSED_HEIGHT_1)
));
}
if(thuData.size() != 0){
scheduleLvItems.add(new Schedule_ListView(
R.drawable.thursday_mdpi,
thuData,
getResources().getInteger(R.integer.COLLAPSED_HEIGHT_1)
));
}
if(friData.size() != 0){
scheduleLvItems.add(new Schedule_ListView(
R.drawable.friday_mdpi,
friData,
getResources().getInteger(R.integer.COLLAPSED_HEIGHT_1)
));
}
if(satData.size() != 0){
scheduleLvItems.add(new Schedule_ListView(
R.drawable.saturday_mdpi,
satData,
getResources().getInteger(R.integer.COLLAPSED_HEIGHT_1)
));
}
if(sunData.size() != 0) {
scheduleLvItems.add(new Schedule_ListView(
R.drawable.sunday_mdpi,
sunData,
getResources().getInteger(R.integer.COLLAPSED_HEIGHT_1)
));
}
//add padding top - bottom for listview
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout header = (LinearLayout) inflater.inflate(R.layout.listview_header, null);
lvSchedule.addFooterView(header, null, false);
lvSchedule.addHeaderView(header, null, false);
//setup listView Adapter
scheduleAdapter = new Schedule_Adapter(Schedule.this, R.layout.schedule_listview, scheduleLvItems);
//setup adapter to listView
lvSchedule.setAdapter(scheduleAdapter);
//setup OnClickListener
lvSchedule.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
int postion = i - lvSchedule.getHeaderViewsCount();
toggle(view, postion);
}
});
}catch (Exception e){
System.out.println(e);
}
}
This is happening because your distributing the data to the ListView
in onCreate and whenever you change the orientation, the activity will be restarted and the onCreate won't be called. Thus, it won't be distributed. to tackle this issue, just move this line and the related lines to onResume
renderData(scheduleJSON); //take more important lines with it to onResume
it should be like the following:
protected void onResume()
{
super.onResume();
renderData(scheduleJSON); //take more important lines with it to onResume
}
Second Solution:
you can prevent the restart of the activity when orientation has changed by adding this to your manifest in the activity tag
<activity android:name="YourActivity"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation"> //this line