Recyclerview custom (Header, Footer, Scrolling, Drag and drop, Swipe 등등..)

구글 공식 사이트를 보면 다양하게 메소드를 제공한다. 하지만 여기서 대부분 많이 사용하는 메소드를 위주로 작성할 것이며, 내가 원하는 UI가 없어서 만들면서 기록을 남기려 합니다.(Recyclerview에 어느정도 알고 있다는 가정하에 글을 작성하겠습니다.

우선, 자주쓰이는 method는 순서대로

getItemCount
getItemViewType
ViewHolder
onCreateViewHolder
onBindViewHolder

이다.

모두 Recyclerview.Adapter에서 불리는 메소드이다.

간단하게 설명하면,

getItemCount : 전체 아이템 개수 return

getItemViewType : ViewType을 return ( Header, footer 또는 중간에 새로운 layout을 삽입할때 사용)

ViewHolder : Recyclerview는 Generic을 사용하여 Viewholder패턴을 만들었다. 여기서 ViewHolder란, 해당 Layout에 대한 정보를 가지고 있는 것을 말한다. ViewHolder는 생성자를 항상 갖는데 이는 Fragment에서 rootview와 비슷한 느낌이라고 보면 된다. view를 injection하는 곳이라고 생각하면 된다.

onCreateViewHolder : 메소드명 그대로 ViewHolder에서 inject된 View를 inflate하는 메소드이다. 여기서는 ViewGroup과 아까 불렸던 getItemViewType에서의 return값인 viewType이 파라미터로 넘어온다. 쉽게 설명하면 뷰를 그리는 메소드 이므로 여기서 viewtype에 따라 자신이 원하는 layout에 inflate하고 viewholder를 반환해주면된다.

onBindViewHolder : 이제 view가 inflate됬으니까, Data를 Bind시켜줘야한다. onBindViewHolder 메소드명에 맞게 자신이 준비해 놓은 List된 Data를 묶어주면 된다.(자바는 null값을 참조하므로 항상 null체크를 해주어야한다. 안그러면 앱죽음. 그래서 TextUtils든 ObjectUtils든 != null 이든 아무거나 사용해서 체크해주면 방지할 수 있다. 공통유틸로 묶는 것도 좋은 방법)

다음은 Recyclerview를 이용하여 Drag and drop & swipe 할 때의 상황이다.

recyclerview에서 자체적인 drag and drop & swipe에 대한 API는 없다. 따라서 v7 widget ItemTouchHelper interface를 사용해야한다. 중요한 콜백메소드로 불리는 순서를 보자면

Doc 참조 :

isItemViewSwipeEnabled
getMovementFlags
isLongPressDragEnabled
onSelectedChanged
onChildDraw
onMove
clearView
onItemClear
onChildDraw

이다.

간단하게 설명하면,
isItemViewSwipeEnabled : 아이템 Swipe가 가능한지 가능하면 true return

getMovementFlags : makeMovementFlags(int dragFlags, int swipeFlags)의 값을 리턴해줘야한다. 말그대로 어떻게 움직이고 있느냐에 따른 flag를 걸어준거라고 볼 수 있다. 자신이 원하는 방향대로 구현해주면 된다. 예를 들어, 레이아웃을 Horizontal로 만들었다면,

final int dragFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;

만약 레이아웃을 Vertical로 만들었다면,

final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;

이와 같이 설정해주고

return makeMovementFlags(dragFlags, swipeFlags);

이렇게 리턴해주면 된다.

isLongPressDragEnabled : 아이템을 dragging + long pressed 되면 true return

onSelectedChanged : ItemTouchHelper 에 의해서 ViewHolder가 drag 또는 swipe 될 때 불린다.

onChildDraw : View가 유저의 interaction에 반응할 때 불린다.

onMove : 아이템이 Old position으로부터 New position으로 이동시 불리고 true return

clearView :