개발을 하던 중, RecyclerViewAdapter를 구현해야 하는 상황이 생겼습니다.
그러다 문득 ViewHolder 내부 메서드를 살펴보았는데, 이 중 position을 반환하는 함수가 정말 다양하다는 사실을 알게 되었습니다.
그럼 position을 반환하는 많은 메서드 중에서, 과연 무슨 함수를 사용해야 하는 것일까?
한 번 차근차근 살펴보도록 하겠습니다!
/**
* @deprecated This method is deprecated because its meaning is ambiguous due to the async
* handling of adapter updates. You should use {@link #getLayoutPosition()} or
* {@link #getAdapterPosition()} depending on your use case.
*
* @see #getLayoutPosition()
* @see #getAdapterPosition()
*/
@Deprecated
public final int getPosition() {
return mPreLayoutPosition == NO_POSITION ? mPosition : mPreLayoutPosition;
}
getPosition() 함수는 지원 라이브러리 22.x 버전부터 Deprecated 되었다고 합니다.
이유는 주석 맨 윗 줄을 읽어보면 알 수 있다시피,
Async에 모호하기 때문에 더 이상 지원하지 않으며, 개발자의 상황에 맞춰서 getLayoutPosition() 또는 getAdapterPosition()을 사용하도록 권장하고 있습니다.
public final int getLayoutPosition() {
return mPreLayoutPosition == NO_POSITION ? mPosition : mPreLayoutPosition;
}
다음은 getLayoutPosition() 입니다.
해당 메서드의 경우, getAdapterPosition()보다 16ms정도 늦게 반영된다고 합니다.
예를 들어, notifyItemRangeChanged(), notifyItemRemoved()와 같이 RecyclerView가 새 레이아웃을 요청합니다.
그 순간부터 레이아웃 시스템이 새 레이아웃을 계산하기에 까지 걸리는 시간이 16ms 정도입니다.
이 시간동안, 아직 어댑터 변경 사항을 반영하지 않았기 때문에 실제 레이아웃의 위치와 어댑터의 위치에 차이가 날 수도 있다는 것입니다.
따라서 position의 정확한 값을 받아낼 수 없을 수도 있다고 합니다.
public final int getAdapterPosition() {
if (mOwnerRecyclerView == null) {
return NO_POSITION;
}
return mOwnerRecyclerView.getAdapterPositionFor(this);
}
getAdapterPosition()은 항상 Holder의 최신 업데이트된 어댑터 위치를 제공한다고 합니다.
위 코드를 보면, RecyclerView가 Null이라면 NO_POSITION을 반환하도록 하고, 그렇지 않은 경우엔 getAdapterPositionFor() 라는 메서드를 호출하여 position을 반환합니다.
즉, Holder를 클릭할 때마다, 어댑터에게 Position을 묻기 때문에, 해당 항목의 최신 위치를 얻을 수 있어 정확한 값을 받아낼 수 있습니다.
따라서, ClickListener를 등록하는 경우가 생긴다면, 리스트의 정확한 인덱스에 접근하기 위해 adapterPosition을 사용하는 것이 좋습니다.
+ 추가 내용
getAdapterPosition() 또한 2020년 2월부터 Deprecated되었다고 합니다.
대신 getAbsoluteAdapterPosition() 또는 getBindingAdapterPosition()을 사용하도록 권장합니다!
이번 시간에는 RecyclerView의 다양한 Position에 대해 알아보았습니다.
본인 또한 지금까지 그 차이를 모르고 써왔지만, 포스팅을 작성하면서 차이를 알지 못하면 프로그램 로직을 구성하는 데에 있어 큰 문제가 발생할 수도 있겠다는 생각을 하였습니다.
항상 더 알려고 하는 습관이 중요한 듯 합니다..ㅎㅎ
긴 글 읽어주셔서 감사합니다.
내용에 오류가 있거나, 질문이 있으신 분들은 댓글을 남겨주시면 감사하겠습니다! 😊
'Android > 스터디' 카테고리의 다른 글
쿠키(Cookie)와 세션(Session)을 이용한 로그인 (2) | 2022.01.21 |
---|---|
[Android] 안드로이드 Strings.xml 국가별 언어 설정 방법 및 국가 코드 정리 (5) | 2021.12.28 |
[Android] MVVM ViewModel 오류 : Can't access ViewModels from detached fragment 해결방법! (4) | 2021.12.19 |
[Android] 카카오맵을 2개 이상 ADD했을 때 발생하는 오류 대처 방법! DaumMap does not support that two or more (2) | 2021.12.17 |
[Android] OutOfMemoryError: Java heap space 오류 해결 방법 (0) | 2021.12.07 |