RecyclerView 可利用極少量圖像資源顯示大量資料。當使用者捲動瀏覽 RecyclerView 中的項目時,系統會重複使用捲動至螢幕外項目的 View 執行個體,以在螢幕上捲動時建立新項目。不過,設定變更 (例如裝置旋轉) 可能會重設 RecyclerView 的狀態,導致使用者必須再次捲動回項目清單中的先前位置。
每當設定變更時,RecyclerView 都應維持原本的狀態 (尤其是捲動位置),清單元素的狀態也不應變動。
結果
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:保留活動或片段的狀態。
包含本指南的集合
本指南是精選快速指南系列的一部分,涵蓋更廣泛的 Android 開發目標: