RecyclerView 상태 관리
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
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. 스테이트풀(Stateful) 목록 항목 상태 저장
EditText
요소가 포함된 항목과 같이 복잡한 RecyclerView
목록 항목의 상태를 저장합니다. 예를 들어 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
에서 목록 항목 상태 복구
ViewHolder
를 항목에 바인딩하면 RecyclerView.Adapter
에서 항목의 상태를 복원합니다.
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)
}
}
자바
@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
에서 스크롤 위치 및 RecyclerView
목록에 있는 모든 항목의 상태를 복원할 수 있습니다.
이 가이드가 포함된 컬렉션
이 가이드는 광범위한 Android 개발 목표를 다루는 선별된 빠른 가이드 모음의 일부입니다.
큰 화면에 최적화
앱이 태블릿, 폴더블, ChromeOS 기기에서 최적화된 사용자 환경을 지원하도록 설정합니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-02-06(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-02-06(UTC)"],[],[],null,["# Manage RecyclerView state\n\n\u003cbr /\u003e\n\n[`RecyclerView`](/reference/kotlin/androidx/recyclerview/widget/RecyclerView) can display large amounts of data using minimal graphical\nresources. As users scroll through the items in a `RecyclerView`, `View`\ninstances of items that have scrolled off screen are reused to create new items\nas they scroll on screen. But configuration changes, such as device rotation,\ncan reset the state of a `RecyclerView`, forcing users to again scroll to their\nprevious position in the list of items.\n\n`RecyclerView` should maintain its state---in particular, scroll\nposition---and the state of its list elements during all configuration\nchanges.\n\nMaintain state\n--------------\n\nSet the state restoration policy of the `RecyclerView.Adapter` to save the\n`RecyclerView` scroll position. Save the state of `RecyclerView` list items. Add\nthe state of the list items to the `RecyclerView` adapter, and restore the state\nof list items when they're bound to a `ViewHolder`.\n\n### 1. Enable `Adapter` state restoration policy\n\nEnable the state restoration policy of the `RecyclerView` adapter so that the\nscrolling position of the `RecyclerView` is maintained across configuration\nchanges. Add the policy specification to the adapter constructor: \n\n### Kotlin\n\n```kotlin\nclass MyAdapter() : RecyclerView.Adapter\u003cRecyclerView.ViewHolder\u003e() {\n init {\n stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY\n }\n ...\n}\n```\n\n### Java\n\n```java\nclass MyAdapter extends RecyclerView.Adapter\u003cRecyclerView.ViewHolder\u003e {\n\n public Adapter() {\n setStateRestorationPolicy(StateRestorationPolicy.PREVENT_WHEN_EMPTY);\n }\n ...\n}\n```\n\n### 2. Save the state of stateful list items\n\nSave the state of complex `RecyclerView` list items, such as items that contain\n`EditText` elements. For example, to save the state of an `EditText`, add a\ncallback similar to an `onClick` handler to capture text changes. Within the\ncallback, define what data to save: \n\n### Kotlin\n\n```kotlin\ninput.addTextChangedListener(\n afterTextChanged = { text -\u003e\n text?.let {\n // Save state here.\n }\n }\n)\n```\n\n### Java\n\n```java\ninput.addTextChangedListener(new TextWatcher() {\n\n ...\n\n @Override\n public void afterTextChanged(Editable s) {\n // Save state here.\n }\n});\n```\n\nDeclare the callback in your `Activity` or `Fragment`. Use a `ViewModel` to\nstore the state.\n\n### 3. Add list item state to the `Adapter`\n\nAdd the state of list items to your `RecyclerView.Adapter`. Pass the item state\nto the adapter constructor when your host `Activity` or `Fragment` is created: \n\n### Kotlin\n\n```kotlin\nval adapter = MyAdapter(items, viewModel.retrieveState())\n```\n\n### Java\n\n```java\nMyAdapter adapter = new MyAdapter(items, viewModel.retrieveState());\n```\n\n### 4. Recover list item state in the adapter's `ViewHolder`\n\nIn the `RecyclerView.Adapter`, when you bind a [`ViewHolder`](/reference/kotlin/androidx/recyclerview/widget/RecyclerView.ViewHolder) to an item,\nrestore the item's state: \n\n### Kotlin\n\n```kotlin\noverride fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {\n ...\n val item = items[position]\n val state = states.firstOrNull { it.item == item }\n\n if (state != null) {\n holder.restore(state)\n }\n}\n```\n\n### Java\n\n```java\n@Override\npublic void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {\n ...\n Item item = items[position];\n Arrays.stream(states).filter(state -\u003e state.item == item)\n .findFirst()\n .ifPresent(state -\u003e holder.restore(state));\n}\n```\n\nKey points\n----------\n\n- [`RecyclerView.Adapter#setStateRestorationPolicy()`](/reference/kotlin/androidx/recyclerview/widget/RecyclerView.Adapter.StateRestorationPolicy): Specifies how a `RecyclerView.Adapter` restores its state after a configuration change.\n- [`ViewModel`](/reference/kotlin/androidx/lifecycle/ViewModel): Holds state for an activity or fragment.\n\nResults\n-------\n\nYour `RecyclerView` is now able to restore its scroll position and the state of\nevery item in the `RecyclerView` list.\n\nCollections that contain this guide\n-----------------------------------\n\nThis guide is part of these curated Quick Guide collections that cover broader\nAndroid development goals: \n\n### Optimize for large screens\n\nEnable your app to support an optimized user experience on tablets, foldables, and ChromeOS devices. \n[Quick guide collection](/quick-guides/collections/optimize-for-large-screens) \n\nHave questions or feedback\n--------------------------\n\nGo to our frequently asked questions page and learn about quick guides or reach out and let us know your thoughts. \n[Go to FAQ](/quick-guides/faq) [Leave feedback](https://issuetracker.google.com/issues/new?component=1573691&template=1993320)"]]