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 기기에서 최적화된 사용자 환경을 지원하도록 설정합니다.

질문이나 의견이 있으신가요?

자주 묻는 질문(FAQ) 페이지로 이동하여 빠른 가이드를 알아보거나 문의하여 의견을 보내주세요.