LinearLayout.addView(View视图)方法调用的IllegalStateException

时间:2010-12-29 15:59:16

标签: android

有人可以告诉我为什么会发生这种情况,请阅读以下内容。 我有自己的类Data,它扩展了Button。在我的Activity类中,我有一个List,它会在每次单击按钮时附加新的Data对象。我想在配置更改后,在屏幕上保留创建的类Data对象,即方向更改。所以我已经覆盖了onSaveInstanceState()并使用它来恢复onCreate()方法中的数据。在提到的方法中,我将从对象列表中保存每个Data对象。在onCreate()方法中,我正在尝试恢复我的数据:

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  
                }  
            }  
        }  

所以在第一种情况下我得到了IllegalStateException,但它对第二种情况很有用。我不明白其中的区别。

以防万一,这是我的onSaveInstanceState()方法:

@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);  
        }  
    }  

我的数据类,但没什么特别的:

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);  
    }  

}  

2 个答案:

答案 0 :(得分:4)

  1. 原始问题:

    在这种情况下抛出IllegalStateException,因为子视图(在您的情况下为Button / Data)已经有父(ViewGroup或在您的情况下为LinearLayout)。这意味着您只能将视图添加到视图组一次。如果要将它们添加到新的ViewGroup,则必须先在原始ViewGroup上调用.removeView()

    由于您要将数据对象保存到包,我假设您多次调用.addView(data)而未在其间调用.removeView(data)

  2. 其他问题:

    您正在将数据保存到捆绑包。数据扩展Button不是可序列化的,因此您不应将Data标记为Serializable。

    为什么首先将按钮保存到捆绑包中?

答案 1 :(得分:0)

我唯一可以说的是不保存小部件或任何需要这样的上下文的东西。当方向发生变化时,活动将被销毁并使用新上下文创建。这就是你看错的原因。这些按钮有什么作用?为什么有那么多,你为什么要继承按钮?为什么他们称为数据?通常,数据与按钮无关。