![](/img/trans.png)
[英]OnRestoreInstanceState() not applied on View IDs that have been set programmatically
[英]onRestoreInstanceState() and Unique View Ids
android 開發人員指南說,您活動中的Views
需要具有唯一 ID,以便在onRestoreInstanceState()
中恢復它們。 這是因為onRestoreInstanceState()
通過創建一個以 id 作為鍵的SparseArray
來工作。
我覺得這非常奇怪,因為許多標准 Android 方法都鼓勵重復使用 ID。 例如, ArrayAdapter
的所有構造函數都將 resourceId 作為參數,因此相同的 xml 資源會為ListView
中的所有子項擴充。 同樣,如果您在 xml 中使用<include layout...>
,您就是在重復使用視圖 ID。
因此,除非開發人員實際上沒有使用標准的、推薦的方法,否則我看不到有很多應用程序實際上滿足所有Views
都具有唯一 ID 的要求。
這個結論錯了嗎? 另外,如果 id 不完全不同, onRestoreInstanceState
的行為是什么,這種行為是否可以接受?
編輯
相關引述出現在http://developer.android.com/training/basics/activity-lifecycle/recreating.html頁面,內容如下:
注意:為了讓 Android 系統恢復您活動中視圖的 state,每個視圖必須有一個唯一的 ID,由 android:id 屬性提供。
注意:始終調用 onRestoreInstanceState() 的超類實現,以便默認實現可以恢復視圖層次結構的 state。
AdapterView
(所有使用Adapter
ViewGroup
的基類),以便不保存或還原其子View
的狀態,因為這是Adapter
的域,應在該級別上進行處理。
對於在多個點靜態包含的子布局,如果要保存任何狀態,則需要為所有有狀態View
分配唯一的ID,或者從Activity
或Fragment
手動管理狀態。
不幸的是,id在整個View
結構中必須是唯一的,而不僅僅是它們之間的同級。 這是由於以下事實:整個結構的狀態保存在一個一維SpareArray
。 因此,如果結構中有多個共享相同ID的有狀態View
,則僅保存結構中最后一個狀態的狀態,並將在狀態恢復時將其應用於具有該ID的所有View
。
一種簡單的解決方案是以編程方式分配ID 。
ID不是一成不變的,因此您可以在視圖創建期間更改 ID。
假設您膨脹了一些視圖MyCustomView
,其中有一些名為 nameEditText 的EditText
。 在創建視圖時,您可以擁有以下內容:
binding.view1.nameEditText.id = R.id.pageX_field1
binding.view2.nameEditText.id = R.id.pageX_field2
這樣 save state 將根據給定的 ID 存儲值。 state 的恢復將在創建視圖后發生。
為此,您可以在資源文件中創建您的 ID:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- PAGE X IDS -->
<item type="id" name="pageX_field1" />
<item type="id" name="pageX_field2" />
</resources>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.