GridLayoutManager를 사용해 RecyclerView를 구현하던 중, 스크롤을 최하단부로 내린 뒤, 아이템을 클릭하면 다음과 같은 에러가 발생했다.
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder
아이템을 클릭하면 데이터를 삽입하고 삭제하는 과정이 반복적으로 발생하게끔 구현되어있었는데, 처음에는 이 때문에 생긴 에러인 줄 알았다.
근데 이상하게도 위 ~ 중간의 아이템을 클릭할 땐 문제가 없었고, 마지막 두줄 정도?의 아이템을 클릭할 때만 발생했다. 하하
아무튼 찾아보니, 삼성 기기에서만 발생하는 리사이클러 뷰 스크롤 에러라고 하는데..
흠.. 아직도 정확한 원인은 잘 모르겠다.
스택오버플로우 글을 참고해서 다음 Wrapper Class를 구현해주었다.
class GridLayoutManagerWrapper: GridLayoutManager {
constructor(context: Context, spanCount: Int) : super(context, spanCount) {}
constructor(context: Context, spanCount: Int, orientation: Int, reverseLayout: Boolean) : super(context, spanCount, orientation, reverseLayout) {}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {}
override fun supportsPredictiveItemAnimations(): Boolean {
return false
}
}
val layoutManager = GridLayoutManagerWrapper(this@Activity, 2)
recyclerView.layoutManager = layoutManager
그랬더니 잘 동작해버림~!
그리고 이 전에도 동일한 에러가 발생했었는데, 그때는 갱신 문제였던 것 같다.
데이터를 변경한 뒤, 이를 알리기 위해 notifyItemRangeChanged()를 중복해서 사용했다.
아마 중복해서 실행되는 과정에서 데이터 불일치가 감지된게 아닐까... 추측해본다.