2

上下文

当您创建一个新的 android 项目时,我的应用程序架构与默认的“Swipe Views”非常相似。一项活动,3个片段,您可以在其中滑动。它使用支持库。一切都是最新的。我正在测试的设备是运行 android 4.1.2 支持库 r11 和 SDK 版本 min=14 target=16 的 Galaxy nexus

问题

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

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

细节

一个带有 SectionsPagerAdapter、ViewPager 和每个页面的片段的活动。

在方法中的一个片段(ConfigurationFragment)中,我使用 and和 anonViewCreated动态创建行。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 是一个线性布局,它将保存新创建的视图 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>

任何的想法?

我已经盯着这个错误几个小时了,我真的不知道发生了什么......我开始怀疑 SDK 或支持库中的错误,但我从经验中知道这个错误是最经常在我的脑海里:)

4

2 回答 2

4

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

问题是所有的 EditTexts 都具有相同的 id,因此在恢复状态时它搞砸了。

于 2012-11-22T00:05:53.547 回答
0

这不是错误,所以不要担心。问题是,如果您旋转屏幕,将重新创建 Activity 和 Fragments。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);
}
于 2012-11-21T23:25:50.730 回答