So you have a ListView which I assume you have some adapter which in it's get view hosts the progress bars. However that progress must be backed by something right? So just save that data. Like I am assuming an adapter like so:
public class MyProgressBarAdapter extends BaseAdapter {
private ArrayList<Integer> mProgessValues;
private SparseArray<AsyncTask<?,?,?>> mTasks;
// No stored reference to a Context
private MyProgressBarAdapter() {
}
public void saveState(Bundle bundle) {
bundle.putIntegerArrayList(getClass().getName() + ".progressValues", mProgressValues);
}
public Object exportLiveState() {
return mTasks;
}
public static MyProgressBarAdapter restore(Bundle bundle, Object rawState) {
MyProgressBarAdapter adapter = new MyProgressBarAdapter();
Class<MyProgressBarAdapter> c = adapter.getClass();
ArrayList<Integer> progresses = null;
if (bundle != null) {
progresses = bundle.getIntegerArrayList(c.getName() + ".progressValues");
}
if (progresses == null) {
progresses = new ArrayList<Integer>();
}
adapter.mProgressValues = progresses;
if (rawState != null && rawState instanceof SparseArray) {
adapter.mTasks = (SparseArray<AsyncTask<?,?,?>>) rawState;
}
return adapter;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = getViewWithHolder(convertView, parent);
ViewHolder holder = convertView.getTag();
// set the appropriate things on the view elements.
holder.position = position;
holder.taskContainer = mTasks;
holder.progressBar.setProgress(mProgressValues.get(position));
convertView.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
ViewHolder holder = view.getTag();
int pos = holder.position;
SparseArray<AsyncTask> tasks = holder.taskContainer;
AsyncTask task = tasks.get(pos);
if (task == null) {
// Create your task
task = new AsyncTask<?, ?, ?> (...);
tasks.put(pos, task);
task.execute();
}
}
return convertView;
}
/// You can write the rest of the adapter I believe.
...
}
and then you don't really need onConfigurationChanged. Just read and save your data accordingly.
public class MyActivity extends Activity {
ListView mListView;
MyProgressBarAdapter mAdapter;
@Override
public void onCreate(Bundle savedState) {
super.onCreate();
Object[] liveState = getLastNonConfigurationInstance();
setContentView(R.layout.mylistview_with_progressbars);
mListView = findViewById(R.id.listview);
// Be consistent with the index
MyProgressBarAdapter adapter = MyProgressBarAdapter.restore(savedState, liveState[0]);
mListView.setAdapter(adapter);
mAdapter = adapter;
...
}
@Override
public void onSaveInstanceState(Bundle bundle) {
mAdapter.save(bundle);
}
@Override
public Object[] onRetainNonConfigurationInstance () {
// size to be whatever live state you need to store other than the adapter
Object[] objects = new Object[1];
// This reference will be retained between onCreate() and onDestroy() calls.
objects[0] = mAdapter.exportLiveState();
// Any other things that can't be serialized
return objects;
}
@Override
public Object[] getLastNonConfigurationInstance() {
Object[] live = (Object[]) super.getLastNonConfigurationInstance();
if (live == null) {
live = new Object[1];
}
return live;
}
// The rest of your activity
...
}
That will make it so that when you flip the orientation, the adapter will be recreated but it will be reinitialized to the same state it was in before. I made some assumptions about the way you store your progress and the nature of your asyncTasks but I hope you can adjust as needed.
You could even, if you don't store a reference to any context, you might be able to get away with just storing the entire adapter itself inside the onRetainNonConfigurationInstance() and using that in the getLastRetainedNonConfigurationInstance()