본문 바로가기
개발/Android

[Android] 화면 방향 변경 시에도 RecyclerView의 Position 유지하기

by Dev Aaron 2020. 11. 8.
반응형

디바이스 방향을 가로 혹은 세로로 바꾸게 되면 Config가 변경되면서
Activity의 라이프사이클이 다시 onCreate부터 호출됩니다.
즉 RecyclerView의 스크롤이 상단으로 되돌아 가게 되죠.

Config가 변경되어 Activity 종료 라이프사이클을 탈 때 현재 스크롤 정보를 저장하고,
Activity가 다시 시작하는 라이프사이클 때 저장했던 스크롤 정보를 가져와 적용시켜주면 됩니다.

이를 위해 우리가 알아야 할 메서드는 다음 2가지입니다.

public void onSaveInstanceState(Bundle outState);
public void onViewStateRestored(@Nullable Bundle savedInstanceState);

onSaveInstanceState는 종료 라이프사이클 때 불리며,
onRestoreInstanceState는 그와 반대로 생성 라이프사이클 때 불립니다.

그럼 다시 Activity 라이프사이클을 간단히 살펴보면 다음과 같습니다.

생성: onCreate -> onStart -> onResume
종료: onPause -> onStop -> onDestroy

그럼 onSaveInstanceState와 onRestoreInstanceState는 언제 불리느냐?
사실 이 두 함수는 다른 라이브사이클 함수처럼 항상 불리지 않습니다.
리소스 문제로 앱이 부득이 하게 죽거나, 화면 전환, 언어 변경과 같은 Config change가 발생했을 때 불리는 함수로 이해하면 될 것 같습니다.

Activity가 종료되면서 onSaveInstanceState 메서드가 불리며, 이때 현재 RecyclerView의 스크롤 위치 정보를 저장하면 됩니다.
마찬가지로 Fragment가 그려질 때, onViewStateRestored가 불려지며, 이전에 저장했던 정보를 가져와 복구시켜주면 됩니다.

즉 RecyclerView의 상태 정보는 onSaveInstanceState 함수 안에서 저장하면 되며, 코드는 다음과 같습니다.

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putParcelable("key", mRecyclerView.getLayoutManager().onSaveInstanceState());
}

 

저장한 RecyclerView의 상태 정보는 반대로 onRestoreInstanceState 함수에서 복구시켜주면 됩니다. 코드는 아래와 같습니다.

@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
    super.onViewStateRestored(savedInstanceState);
    if (savedInstanceState != null) {
        mLayoutManagerSavedState = savedInstanceState.getParcelable("key");
    }
}

@Override
public void onStart() {
    super.onStart();
    if (getArguments() != null) {
        mDataArray = getArguments().getParcelableArrayList("key_datas");

        mAdapter = new MyAdapter(mDataArray, getContext());
        mRecyclerView.setAdapter(mAdapter);

        if (mLayoutManagerSavedState != null) {
            mRecycleriew.getLayoutManager().onRestoreInstanceState(mLayoutManagerSavedState);
        }
    }
}

참고로 Fragment의 경우는 onRestoreInstanceState 대신 onViewStateRestored 가 존재합니다.

반응형