考虑以下过于简化的示例。我有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.list
和R.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时,如何正确恢复状态?)
答案 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
的下一次启动时,您的适配器将读取这些存储的值,并且它们将被正确恢复。
希望其中一个选项可以帮到你。