[Android] bindingAdapterPosition vs. absoluteAdapterPosition

ByWindow·2023년 2월 7일
1

Android

목록 보기
12/14
post-thumbnail

adapterPosition is Deprecated


Android Jetpack에서 제공되는 RecyclerView 라이브러리가 1.2.0 버전으로 변경되면서(2021년 4월 7일) 기존에 사용하던 adapterPosition(getAdapterPosition) 메서드의 지원이 중단되었습니다.
그 이유를 살펴보면, 여러 어댑터를 연결하기 위한 concatAdapter 메서드가 등장하면서 기존의 adapterPosition을 통한 아이템의 position을 가져오는 작업이 모호해졌다는 것입니다.
어댑터 하나에 바인딩된 리스트에서 position을 원하는지, RecyclerView 전체에 대한 position을 원하는지에 대한 혼란이 있기 때문에, 이 두가지 경우를 구분하도록 변경되었습니다.

bindingAdapterPosition


현재 ViewHolder 클래스가 존재하는 Adapter에서의 position을 반환합니다.
RecyclerView에 하나의 어댑터만 사용하고 있다면 이 메서드를 사용해서 아이템의 position을 가져올 수 있습니다.

public final int getBindingAdapterPosition() {
	if (mBindingAdapter == null) {
		return NO_POSITION;
	}
	if (mOwnerRecyclerView == null) {
		return NO_POSITION;
	}
	@SuppressWarnings("unchecked")
	Adapter<? extends ViewHolder> rvAdapter = mOwnerRecyclerView.getAdapter();
	if (rvAdapter == null) {
		return NO_POSITION;
	}
	int globalPosition = mOwnerRecyclerView.getAdapterPositionInRecyclerView(this);
	if (globalPosition == NO_POSITION) {
		return NO_POSITION;
	}
	return rvAdapter.findRelativeAdapterPositionIn(mBindingAdapter, this, globalPosition);
}

마지막 리턴문을 보면 알 수 있듯이, 어댑터에 접근하여 positon을 가져오고 있습니다.

getBindingAdapterPosition vs. getLayoutPosition

공식문서를 보면, getBindingAdapterPositiongetLayoutPosition은 다르다는 것을 알려주고 있습니다.
RecyclerView가 데이터 변화에 대한 notify를 듣고 새로운 레이아웃을 그리는데 보통 16ms가 걸리는데, 이 시간동안 어댑터는 변경사항을 반영하지 않기 때문에 getLayoutPosition으로 받아오는 실제 레이아웃의 위치에 getBindingAdapterPosition로 받아오는 어댑터의 위치가 차이가 날 수 있고 position의 정확한 값이 아닐 수 있습니다.

absoluteAdapterPosition


RecyclerView에서의 "절대적" position을 반환합니다.

public final int getAbsoluteAdapterPosition() {
	if (mOwnerRecyclerView == null) {
		return NO_POSITION;
	}
	return mOwnerRecyclerView.getAdapterPositionInRecyclerView(this);
}

코드에서 볼 수 있듯이, RecyclerView 전체에 대해서 position을 가져오는 것을 알 수 있습니다.
따라서, concat 유무에 상관없이 absoluteAdapterPosition는 동일한 position을 반환합니다.
예를 들어, A adapter 와 B adapter를 ConcatAdapter로 연결한 경우에서
B Adapter의 세번째 아이템의 위치를 bindingAdapterPosition로 가져온 경우에는 2(B adapter에서의 position)를 반환하지만
absoluteAdapterPosition로 가져온 경우에는 ((A adapter에 바인딩된 item 개수 - 1) + 2)를 반환합니다.

profile
step by step...my devlog

1개의 댓글

comment-user-thumbnail
2023년 9월 21일

좋은 글 감사합니다~

답글 달기