安卓: 为什么我的EditText在屏幕方向改变后仍然保留值?

3

这只是一个好奇的问题。

最近我学到在屏幕旋转时需要自己保存活动状态,但是在我的一个布局中,EditText仅保留了其值,我不知道原因。显然,我想为其他EditText复制此行为...

这是布局,EditText的ID为android:id="@+id/createlistactivity_listname_edittext"

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<LinearLayout
    android:id="@+id/linearLayout2"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:drawable/title_bar"
        android:gravity="center"
        android:text="Enter a Name"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/createlistactivity_listname_edittext"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:hint="Name..."
        android:singleLine="true" >

    </EditText>

</LinearLayout>


<LinearLayout
    android:id="@+id/linearLayout1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/CreateListActivity_HeaderLabel"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:drawable/title_bar"
        android:gravity="center"
        android:text="Add Products to your new List"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:choiceMode="multipleChoice"
        android:footerDividersEnabled="true" >
    </ListView>

    <TextView
        android:id="@android:id/empty"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:paddingLeft="8dp"
        android:paddingRight="8dp"
        android:text="No Products available. Insert some Products in the Products menu  first" />

</LinearLayout>


<LinearLayout
    android:orientation="horizontal"
    android:id="@+id/CreateListActivity_BottomBar"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:weightSum="2"
    style="@android:style/ButtonBar" >


    <ImageButton
        android:id="@+id/CreateListActivity_SaveButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:background="@android:color/transparent"
        android:onClick="saveButtonClicked"
        android:src="@drawable/tick_32" />


    <ImageButton
        android:id="@+id/CreateListActivity_CancelButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:background="@android:color/transparent"
        android:onClick="cancelButtonClicked"
        android:src="@drawable/block_32_2" />

</LinearLayout>

</LinearLayout>

这里是活动的onCreate方法:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.createlistactivity_layout);

    _selectedItems = new HashMap<Integer, Integer>();
    _productDAO = new ProductDAO(getApplication());
    _listDAO = new ListDAO(getApplication());
    _productCursor = _productDAO.getAllProductsCursor();

    startManagingCursor(_productCursor);

    setUpListView();    

    final EditText listNameEditText = (EditText)this.findViewById(R.id.createlistactivity_listname_edittext);

    listNameEditText.setOnEditorActionListener(new OnEditorActionListener() {

        public boolean onEditorAction(TextView v, int actionId,
                KeyEvent event) {
            if (event != null&& (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
                InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                in.hideSoftInputFromWindow(listNameEditText
                        .getApplicationWindowToken(),
                        InputMethodManager.HIDE_NOT_ALWAYS);
            }
            return false;
        }
    });     
}

这是另一个活动的代码,其中包含不保留其状态的EditText。

  <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >


<TableLayout
    android:id="@+id/TableLayout1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_below="@id/productImage"
    android:background="@android:drawable/alert_light_frame" >

    <TableRow
        android:id="@+id/productview_toprow"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="top" >

        <EditText
            android:id="@+id/productview_productname"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:hint="Product Name"
            android:singleLine="true" >

            <requestFocus />
        </EditText>
    </TableRow>

    <TableRow
        android:id="@+id/tableRow2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:layout_weight="1"
            android:gravity="center_vertical|center_horizontal"
            android:text="@string/productview_pricelabel"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@android:color/black" />

        <EditText
            android:id="@+id/productview_price_edittext"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="0.0"
            android:singleLine="true"
            android:inputType="numberDecimal" />
    </TableRow>

    <TableRow
        android:id="@+id/tableRow3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center_vertical|center_horizontal"
            android:text="@string/productview_unitlabel"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@android:color/black" />

        <EditText
            android:id="@+id/productview_unit_edittext"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="kg|ml|..." />
    </TableRow>
</TableLayout>

在onCreate方法中...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.productview);

    _productName = (EditText)findViewById(R.id.productview_productname);
    _productPrice = (EditText)findViewById(R.id.productview_price_edittext);
    _productUnit = (EditText)findViewById(R.id.productview_unit_edittext);
    _productImage = (ImageButton)findViewById(R.id.productImage);

    _productDAO = new ProductDAO(getApplication()); 

    //set data from database
    _product = _productDAO.getProduct(getIntent().getExtras().getString(DataBaseKeys.PRODUCT_NAME));

    if(_product != null)
    {
        _productName.setText(_product.getName());
        _productImage.setImageBitmap(_product.getIcon());
        _productPrice.setText(""+_product.getPrice());
        _productUnit.setText(_product.getUnit());
        _productIcon = _product.getIcon();
    }           

}

你的意思是其他布局中的其他EditText没有维持它们的值吗?你能否添加一些来自它们活动的代码? - Dimitris Makris
是的,他们不会。我将把另一个活动的代码编辑到问题中。 - user1078083
2个回答

4
在安卓中,View会保留一些状态。例如,EditText会保留其文本,所以您不必在onSaveInstanceState中保存它。其他例子包括ListView保留滚动位置,如果是多行文本,则EditText也会保留滚动位置。
但有些事情需要用户自己注意,比如如果您正在使用便签应用程序,则必须存储正在编辑的便签ID,这样在方向更改时就知道您正在处理什么内容。
这是安卓的标准方式,在此没有什么不寻常的。有关更多详细信息,请参见:保存活动状态 至于您的某个活动未按预期工作的原因是代码:
 _product = _productDAO.getProduct(getIntent().getExtras().getString(DataBaseKeys.PRODUCT_NAME));

if(_product != null)
{
    _productName.setText(_product.getName());
    _productImage.setImageBitmap(_product.getIcon());
    _productPrice.setText(""+_product.getPrice());
    _productUnit.setText(_product.getUnit());
    _productIcon = _product.getIcon();
}           

您正在覆盖编辑文本的值。在if语句之前尝试使用此日志语句。

Log.i("EDIT_NOT_WORKING", "VALUE OF EDIT: " + _productName.getText());

您应该看到它会打印出输入的值。


好的,问题在于其他EditText元素无法保存输入。我没有看到任何可能导致这种行为的区别。 - user1078083
所以你的意思是,你有一个名为 EditText a 的控件,它的值为 "Hello",但当屏幕方向改变时,它又变为空了? - havexz
我有一个包含EditText的布局A和一个Activity A。如果您输入“Hello”并更改方向,则会保留“Hello”。我还有另一个包含EditText的布局B和一个Activity B。如果您输入“Hello”并更改方向,那么“Hello”就会消失。这两个问题都在发布中。 - user1078083
你好havexz,感谢你的回答。不幸的是,它是不正确的。日志语句打印了一个空字符串。我只有在产品在数据库中时才填充edittext,这部分正常工作。只有当用户创建新条目时才会发生错误(if语句将不会执行)。 - user1078083
你可以尝试注释掉那个 if 代码块,然后再试一次吗?在我看来,你好像是在 onPause 方法中保存了空的产品。onPause 方法会在屏幕方向改变时被调用。 - havexz
嗨,havexz,感谢你的帮助。在尝试了你的建议后,我感到沮丧,并删除了自动生成的 R 文件几次……现在它可以很好地重新填充 edittexts。 - user1078083

0

如果您不给EditText一个ID,它在屏幕更改时不会保存值。您必须给它一个ID,以便即使屏幕方向改变,该值也能得到保存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接