개발일지

Android in A..Z - RecyclerView (Selection - ItemKeyProvider) 본문

Android (안드로이드)/RecyclerView

Android in A..Z - RecyclerView (Selection - ItemKeyProvider)

강태종 2021. 9. 18. 13:11

RecyclerView Selection에서 선택한 ViewHolder의 키 값을 가져오기 위해 ItemKeyProvider를 사용한다.

보통의 경우 StableIdKeyProvider를 사용할 수 있다. 하지만 StableIdKeyProvider은 내부적으로 Cache 기능을 사용하기 때문에 Selection이 등록된 후 Item을 제거하는 기능을 사용하면 내부적으로 동기화가 되지 않는다.

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.taetae98.qrreader, 
PID: 30548 java.lang.IllegalArgumentException at androidx.core.util.Preconditions.checkArgument(Preconditions.java:38)
at androidx.recyclerview.selection.DefaultSelectionTracker.anchorRange(DefaultSelectionTracker.java:288)
at androidx.recyclerview.selection.MotionInputHandler.selectItem(MotionInputHandler.java:60)
at androidx.recyclerview.selection.TouchInputHandler.onLongPress(TouchInputHandler.java:164)
at androidx.recyclerview.selection.GestureRouter.onLongPress(GestureRouter.java:97)
at android.view.GestureDetector.dispatchLongPress(GestureDetector.java:963)
at android.view.GestureDetector.access$300(GestureDetector.java:70)
at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:340)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8587)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

위와 같은 에러가 발생하는 경우 ItemKeyProvider를 직접 구현하자.


    class BarcodeDataKeyProvider(private val recyclerView: RecyclerView) : ItemKeyProvider<Long>(SCOPE_MAPPED) {
        override fun getKey(position: Int): Long? {
            return recyclerView.findViewHolderForAdapterPosition(position)?.itemId
        }

        override fun getPosition(key: Long): Int {
            return recyclerView.findViewHolderForItemId(key).bindingAdapterPosition
        }
    }

ItemKeyProvider의 파라미터를 SCOPE_MAPPED로 전달하자.

Comments