Android

AdapterPosition과 LayoutPosition 뭐가 달라요?

2023. 12. 14. 16:39
목차
  1. 💡 Intro
  2. 1️⃣ AdapterPosition(BindingAdapterPosition)
  3. 2️⃣ LayoutPosition
  4. 정리
  5. 참고

💡 Intro

리사이클러뷰를 사용하다보면 유저가 특정 아이템을 클릭했을 때 처리를 해줘야 할 필요가 있다. 이를 구현하는 방법은 여러가지가 있겠지만 나는 Activity → Adapter → ViewHolder로 람다를 전달하는 방식으로 구현한다. 이렇게 구현하면 어댑터나 뷰홀더가 어느 함수에 강하게 결합되어 있지 않기 때문에 재사용하기 좋아진다.

 

그런데 아이템을 클릭했을 때 해당 뷰홀더가 가지고 있는 데이터를 사용하여 어떤 작업을 하기 위해서는 약간의 처리가 더 필요하다.

클릭한 뷰홀더에 바인딩 되어있는 String을 사용해야 한다고 가정하자.

그러면 Activity → Adapter → ViewHolder로 전달하는 람다가 다음과 같이 될 것이다.

Activity → Adapter   : (String) -> Unit
Adapter → ViewHolder : (Int) -> Unit

여기서 String은 클릭한 뷰홀더에 바인딩 되어있는 값이고, Int는 String을 가져오기 위한 Position이다.

뷰홀더에서는 이를 위해 AdapterPosition과 LayoutPosition을 사용할 수 있다. 그런데 둘 중 어느것을 써도 아무런 문제가 발생하지 않는다. 어떤 차이가 있는지 궁금해서 알아보게 되었다.

 

 

1️⃣ AdapterPosition(BindingAdapterPosition)

공식문서를 보면 다음과 같이 설명한다.

 

그러니까 리사이클러뷰의 데이터가 변경되면 notify* 메서드를 사용해서 데이터의 변경을 어댑터에 알려준다. 그러면 변경된 데이터를 감지하고 뷰를 다시 그리는 과정이 진행된다.

위 과정이 16ms미만이기 때문에 크게 중요하진 않지만 뷰홀더 위치를 사용하여 어댑터에 접근하려는 경우 문제가 될 수 있다. 그려져있는 뷰홀더의 위치를 사용하여 어댑터에서 데이터를 가져오려고 하면 실제와 다른 데이터가 전달될 수 있는 것이다.

 

 

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

getAdapterPosition은 위에 보이는 것처럼 RecyclerView의 Adapter에 접근해서 해당 뷰홀더가 어디에 위치하는지를 반환한다.

이 때문에 notifyDataSetChanged를 호출한 경우에는, 다음 레이아웃 패스까지 이 메서드의 반환 값은 NO_POSITION이 된다고 한다.

 

 

2️⃣ LayoutPosition

역시나 공식문서를 먼저 봐보도록 하자.

 

그러니까 데이터 변경 이후 레이아웃이 다시 그려진 이후의 뷰홀더의 위치를 반환하기 때문에 뷰가 그려지기 전까지 (16ms 이전까지) AdapterPosition과 값이 다를 수 있다.

앞서 이야기한 것처럼 notify* 메서드를 통해 데이터의 변경을 알리면 레이아웃을 요청하고 그리는데까지 16ms 정도가 걸리고 이 시간만큼 AdapterPosition과 값이 다른 것이다.

 

 

public final int getLayoutPosition() {
	return mPreLayoutPosition == NO_POSITION ? mPosition : mPreLayoutPosition;
}

 

 

정리

AdapterPosition을 사용하면 데이터 변경 이후 16ms 이전에도 정확한 위치에 접근이 가능하고 16ms 이후에도 정확한 위치에 접근이 가능하다.

LayoutPosition을 사용하면 데이터 변경 이후 16ms 이전에는 정확한 위치에 접근할 수 없고 16ms 이후에는 정확한 위치에 접근이 가능하다.

여기서 말하는 16ms는 공식문서에서 제공하는 정량적 수치이고 이 것이 의미하는 바는 뷰의 업데이트가 완료 되었는가이다.

 

그럼.. LayoutPosition은 언제 사용하지?

RecyclerView 컴포넌트가 어댑터 업데이트를 느리게 처리하는 동안 일관성을 유지하기 위해 주로 사용됩니다.

이 말이 무슨 말인지 아직은 모르겠다.

 

 

참고

https://proandroiddev.com/difference-between-position-getadapterposition-and-getlayoutposition-in-recyclerview-80279a2711d1

https://velog.io/@paulus0617/Android-bindingAdapterPosition-vs.-absoluteAdapterPosition

 

  1. 💡 Intro
  2. 1️⃣ AdapterPosition(BindingAdapterPosition)
  3. 2️⃣ LayoutPosition
  4. 정리
  5. 참고
'Android' 카테고리의 다른 글
  • DiffUtil 톺아보기
Krrong
Krrong
노는게 제일 좋아Krrong 님의 블로그입니다.
Krrong
노는게 제일 좋아
Krrong
전체
오늘
어제
  • 분류 전체보기 (105)
    • Android (2)
    • 우아한테크코스 (45)
      • Level 5 ~ (2)
      • Level 4 (8)
      • Level 3 | Project (8)
      • Level 2 (12)
      • Level 1 | Mission (4)
      • Level 1 | 정리 (5)
      • 프리코스 (6)
    • AI⦁딥러닝 (5)
    • Jetson Xavier (9)
    • Computer Vision (6)
      • GoProCam (2)
      • OpenCV (4)
    • Git (5)
    • Spring (5)
    • 활동 (5)
    • 기타 (3)
    • 🇩🇪 (13)
      • 일상 (13)
    • ✈️ 여행 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기
  • 티스토리홈

공지사항

인기 글

태그

  • 퀵소트
  • 정렬알고리즘
  • 알고리즘

최근 댓글

최근 글

hELLO · Designed By 정상우.
Krrong
AdapterPosition과 LayoutPosition 뭐가 달라요?
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.