正确的方法来保存和恢复一个布局的多个版本的状态

时间:2014-10-12 03:52:40

标签: android android-layout android-orientation

考虑以下过于简化的示例。我有LinearLayout个项目列表(EditTexts)。在编译时不知道项目的数量(例如,它可能是用户刚刚选择了玩家数量的游戏菜单屏幕,并且在该屏幕上他们正在输入每个玩家的名字)。

显而易见的方法是在xml(R.layout.list)中定义容器布局,并在xml(R.layout.item)中定义单个项布局;看起来像这样:

public class Main extends Activity {
    private static final String FRAG_TAG = "ITEMS_FRAGMENT";
    private static final int NUM_ITEMS = 3;

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

        LinearLayout ll = (LinearLayout) getLayoutInflater().inflate(R.layout.list, null, false);
        for (int i = 0; i<NUM_ITEMS; i++) {
            ll.addView(getLayoutInflater().inflate(R.layout.item, null, false));
        }
        setContentView(ll);
    }
}

分别使用R.layout.listR.layout.item布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/list" />
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/item"
    android:singleLine="true"/>

问题在于,在方向更改时,所有项目具有相同ID(R.id.item)的事实会使恢复过程混乱。最终结果是,最后一个项目的状态将恢复为列表中的所有项目(即,如果最后一个项目EditText具有&#34; hi&#34;在其中,每个 EditText在定位机会之后都会有#34; hi&#34;。

在我的代码中的这个例子中,每个项目都有一个CheckBox,我可以通过isCheckboxChecked(LinearLayout list, int itemNumber)函数获得状态,该函数依赖于每个项目都有一个带ID的视图{ {1}}。是否有一种正确的方法来执行视图状态恢复,接受可能有多个项目从同一XML资源中膨胀(因此具有相同的ID)?

R.id.checkbox不适用于这种情况,但它会正确处理这个问题。当所有项目通常具有相同的ID时,如何正确恢复状态?)

1 个答案:

答案 0 :(得分:3)

Android通过将状态与元素的ID相关联来存储状态。如果所有元素具有相同的ID,则与此ID关联的状态将还原到具有此ID的所有元素。 LisView的做法截然不同。它始终按元素位置从Adapter读取值。由于具有相同ID的视图在列表中具有不同的位置,因此它们也将具有不同的值。

如果你的情况,你有几个选择。

1)您需要先为商品分配不同的ID,然后再通过调用LinearLayout方法将其添加到setId()。您需要在Android资源中定义这些ID(例如<item type="id" name="item_01" />等)。

2)您需要覆盖onSaveInstanceState(Bundle outState),浏览LinearLayout的子项并将其文本存储到outState捆绑关联文本与子项索引中。然后在onRestoreInstanceState()中,您需要阅读savedInstanceState中的状态并相应地将它们设置为您的观点。

3)您使用ListView,当用户输入文本时,您的适配器会保留数据(例如,保存到文件或数据库中)。当配置更改时,或者在Activity的下一次启动时,您的适配器将读取这些存储的值,并且它们将被正确恢复。

希望其中一个选项可以帮到你。