안드로이드에 근래에 추가된 AdapterView 중에 RecyclerView가 있다. ListView의 어려운 애니메이션 처리를 간단히 하고 ViewHolder를 강제하는 등 전반적으로 효율적인 처리를 위해 ListView에 비해 변경된 점이 많은 녀석이다.

RecyclerView에서 아이템 삽입/삭제/갱신시에 애니메이션 처리를 위해서 notifyDataSetChanged 대신, notifyItem 으로 시작하는 뷰 갱신처리 메서드를 사용할 수 있다. 대신 이 메서드들의 경우 변화를 줄 아이템의 포지션을 명시적으로 주거나 범위를 지정해줘야 한다.

문제는 이 메서드들 중 notifyItemRangeXX 메서드들 중에 문제가 있는 놈들이 있다는 것이다. 아래 링크를 참조해보자. 스크린샷을 보면 이렇게 많이 검색이 된다.

http://stackoverflow.com/questions/26827222/how-to-change-contents-of-recyclerview-while-scrolling

아이템의 삽입/삭제범위를 정확히 지정 했음에도 불구하고 Inconsistency detected가 나면서 앱이 크래시나는 case가 구글에서 많이 검색이 된다. 일단 사람들의 의견을 봐선 버그일 가능성이 높으며, RecyclerView의 버전이 계속 올라감에도 여전히 해결되진 않은듯 하다.

아래와 같이 LayoutManager의 onLayoutChildren을 오버라이드 함으로써 일단 문제를 회피할 수는 있다. 자세한 추이는 좀 더 지켜보는게 좋겠다.

public class WrapContentLinearLayoutManager extends LinearLayoutManager {
    //... constructor
    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        try {
            super.onLayoutChildren(recycler, state);
        } catch (IndexOutOfBoundsException e) {
            Log.e("probe", "meet a IOOBE in RecyclerView");
        }
    }
}

RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);

recyclerView.setLayoutManager(new WrapContentLinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false));