RecyclerView
可利用極少量圖像資源顯示大量資料。當使用者捲動瀏覽 RecyclerView
中的項目時,系統會重複使用捲動至螢幕外項目的 View
例項,以在螢幕上捲動時建立新項目。不過,設定變更 (例如裝置旋轉) 可能會重設 RecyclerView
的狀態,導致使用者必須再次捲動回項目清單中的先前位置。
每當設定變更時,RecyclerView
都應維持原本的狀態 (尤其是捲動位置),清單元素的狀態也不應變動。
維持狀態
設定 RecyclerView.Adapter
的狀態還原政策,儲存 RecyclerView
捲動位置。接著儲存 RecyclerView
清單項目的狀態。然後將清單項目的狀態新增至 RecyclerView
轉接程式,並在清單項目繫結至 ViewHolder
時還原清單項目狀態。
1. 啟用 Adapter
狀態還原政策
啟用 RecyclerView
轉接程式的狀態還原政策,以便在任何設定變更時保留 RecyclerView
的捲動位置。請將政策規格新增至轉接程式建構函式:
Kotlin
class MyAdapter() : RecyclerView.Adapter<RecyclerView.ViewHolder>() { init { stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY } ... }
Java
class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public Adapter() { setStateRestorationPolicy(StateRestorationPolicy.PREVENT_WHEN_EMPTY); } ... }
2. 儲存有狀態清單項目的狀態
儲存複雜 RecyclerView
清單項目的狀態,例如包含 EditText
元素的項目。舉例來說,如要儲存 EditText
的狀態,請新增與 onClick
處理常式類似的回呼,以擷取文字變更。然後在回呼中,定義要儲存的資料:
Kotlin
input.addTextChangedListener( afterTextChanged = { text -> text?.let { // Save state here. } } )
Java
input.addTextChangedListener(new TextWatcher() { ... @Override public void afterTextChanged(Editable s) { // Save state here. } });
在 Activity
或 Fragment
中宣告回呼。使用 ViewModel
儲存狀態。
3. 將清單項目狀態新增至 Adapter
將清單項目的狀態新增至 RecyclerView.Adapter
。請在主機 Activity
或 Fragment
建立時,將項目狀態傳遞至轉接程式建構函式:
Kotlin
val adapter = MyAdapter(items, viewModel.retrieveState())
Java
MyAdapter adapter = new MyAdapter(items, viewModel.retrieveState());
4. 在轉接程式的 ViewHolder
中復原清單項目狀態
在 RecyclerView.Adapter
中,如果您將 ViewHolder
繫結至項目,請還原該項目的狀態:
Kotlin
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { ... val item = items[position] val state = states.firstOrNull { it.item == item } if (state != null) { holder.restore(state) } }
Java
@Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { ... Item item = items[position]; Arrays.stream(states).filter(state -> state.item == item) .findFirst() .ifPresent(state -> holder.restore(state)); }
重點
RecyclerView.Adapter#setStateRestorationPolicy()
:指定在設定變更後,RecyclerView.Adapter
如何還原其狀態。ViewModel
:保留活動或片段的狀態。
結果
RecyclerView
現在可以還原其捲動位置,以及 RecyclerView
清單中各項目的狀態。
包含此指南的集合
本指南是精選的快速指南系列之一,涵蓋更廣泛的 Android 開發目標:
![](https://developer.android.google.cn/static/images/quick-guides/collection-illustration.png?hl=zh-tw)