editTexts在旋转设备时更改其值

时间:2012-11-21 23:11:24

标签: android layout android-activity android-fragments android-edittext

上下文

当您创建新的Android项目时,我的应用程序体系结构与默认名为“Swipe Views”的默认设置非常相似。 一个活动,3个碎片,你可以刷过它们。它使用支持库。 一切都是最新的。 我正在测试的设备是运行android 4.1.2的galaxy nexus 支持库r11和SDK版本min = 14 target = 16

问题

第二个片段包含一堆EditText,其中包含从sharedPreferences读取的各种数值。首次创建Activity时,一切都很好,EditViews都有正确的值,但如果我修改其中一个值,例如555,然后我旋转设备,所有EditText现在都显示555!

整个程序中只有一个 setText,它会在本文后面显示,我试图将其删除,正如预期的那样,在启动活动时,所有EditTexts都会显示默认值(666) ,我修改一个并旋转设备,它们都显示新值!

详情

一个活动包含SectionsPagerAdapter,一个ViewPager和每个页面的几个片段。

onViewCreated方法的一个片段(ConfigurationFragment)中,我使用EditTextImageButton动态创建行。

这些行实际上是一个布局(xml文件),我为每一行添加膨胀,然后我得到editText并调用setText将它的值设置为它应该是什么。

onViewCreated方法:

public void onViewCreated(View view, Bundle savedInstanceState)
{
    // populate ports list on view creation
    ArrayList<String> listenPorts = mServerManagerThread.getListenPorts();
    for (String port : listenPorts)
    {
        EditText v = ((EditText) addListenPortItem().getChildAt(0));
        v.setText(port);
    }

    super.onViewCreated(view, savedInstanceState);
}

自然方法getListenPorts每次调用时都会返回相同的列表(在启动时和旋转设备时)

addListenPortItem基本上做什么:

    // Instantiate a new "row" view.
    final ViewGroup newView = (ViewGroup) LayoutInflater.from(viewGroup.getContext()).inflate(itemResource,
            viewGroup, false);

    // Set a click listener for the "X" button in the row that will remove
    // the row.
    newView.findViewById(R.id.delete_button).setOnClickListener(
            new OnRemoveClickListener(mContainer, viewGroup, newView, emptyListTextResource));

    viewGroup.addView(newView);

viewGroup是一个linearLayout,它将保存新创建的视图 itemResource是以下布局

一行布局:

<?xml version="1.0" encoding="utf-8"?>
<!--
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="?android:listPreferredItemHeightSmall"
    android:layout_marginTop="8dp"
    android:divider="?android:dividerVertical"
    android:dividerPadding="8dp"
    android:gravity="right"
    android:orientation="horizontal"
    android:showDividers="middle" >

    <EditText
        android:id="@+id/editPort"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="number"
        android:text="666" >
    </EditText>

    <ImageButton
        android:id="@+id/delete_button"
        style="?android:attr/borderlessButtonStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/action_remove_item"
        android:src="@drawable/content_remove" />
</LinearLayout>

任何想法?

我一直盯着这个bug几个小时了,我真的不知道发生了什么......我开始怀疑SDK或支持库中的一个错误,但我从经验中知道虫子最常出现在我的大脑中:))

2 个答案:

答案 0 :(得分:4)

我找到了解决方案:我将代码从onViewCreated移动到onViewStateRestored(..),以便在状态恢复后填充EditTexts及其值。

问题是所有的EditTexts都有相同的id,因此在恢复状态时它会弄乱它。

答案 1 :(得分:0)

这不是一个错误,所以不要担心。问题是如果旋转屏幕,将重新创建活动和碎片。 onCreateView()将再次被调用,这会混淆,因此你会有这样一种奇怪的行为。你可以通过覆盖这两种方法来解决这个问题:

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    // Read values from the "savedInstanceState"-object and put them in your textview
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    // Save the values you need from your textview into "outState"-object
    super.onSaveInstanceState(outState);
}