Reputation: 60184
can somebody tell me why this happens, please read below. I have my own class Data which extends Button. In my Activity's class I have a List which is appending with new Data object on each button click. I want to keep created objects of class Data on the screen after configuration changes, namely orientation change. So I've overrided onSaveInstanceState() and using it to restore my data in onCreate() method. In mentioned method I'm saving every Data object from the list of objects. In onCreate() method I'm trying to restore my data like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.Button01);
layout = (LinearLayout) findViewById(R.id.MyLayout);
dataList = new ArrayList<Data>();
if(savedInstanceState != null) {
int numberOfObjects = savedInstanceState.getInt("Number of objects");
for (int i = 1; i < numberOfObjects; i++) {
Data tmp = (Data)savedInstanceState.getSerializable("Button name " + i);
if (tmp != null) {
dataList.add(tmp);
}
if (dataList.size() != 0) {
// I'm using one of the lines at a time, uncommented here just for example:
layout.addView((Data)dataList.get(i-1)); // IllegalStateException happens here with advice to invoke removeView() method. I tried to call it on the method beginning, but no success.
layout.addView(new Data(getApplicationContext())); // This one is perfectly fine
}
}
}
So in first case I'm getting IllegalStateException but it is working great for the second one. I don't understand the difference.
Just in case, here is my onSaveInstanceState() method:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d("Dev", "onSaveInstanceState()");
outState.putInt("Number of objects", dataList.size());
for (Data object : dataList) {
outState.putSerializable("Button name " + object.getNumber() , object);
}
}
And my Data class, but nothing special:
package as.as.as;
import java.io.Serializable;
import android.content.Context;
import android.widget.Button;
public class Data extends Button implements Serializable {
public static int counter;
public int number;
public Data(Context context) {
super(context);
counter++;
this.number = counter;
this.setText("Button number " + Integer.toString(number));
}
public String getNumber() {
return Integer.toString(number);
}
}
Upvotes: 0
Views: 1948
Reputation: 80340
The original problem:
The IllegalStateException
is in this case thrown because the child View (in your case Button/Data) already has a parent (a ViewGroup or in your case LinearLayout). This means that you can add Views to View group only once. If you want to add them to a new ViewGroup, then you must first call .removeView()
on the original ViewGroup.
Since you are saving Data objects to bundle I assume that you are calling .addView(data)
multiple times without calling .removeView(data)
in between.
Additional problem:
You are saving Data to a Bundle. Data extends Button which is not Serializable, so you should not mark Data as Serializable.
Why are you saving the Buttons to a bundle in the first place?
Upvotes: 4
Reputation: 48577
The only thing I can say is don't save widgets or anything that requires a context like that. When the orientation changes, the activity is destroyed and created with a new context. That's why you see your error. What do these buttons do? Why are there so many and why are you subclassing buttons? And why are they called Data? Usually Data isn't associated with a button.
Upvotes: 0