classRecyclerViewAdapter:RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>(){// ViewHolder 포지션을 받아 그 위치의 데이터를 삭제하고 notifyItemRemoved로 어댑터에 갱신명령을 전달
funremoveData(position:Int){dataSet.removeAt(position)notifyItemRemoved(position)}// 두 개의 ViewHolder 포지션을 받아 Collections.swap으로 첫번째 위치와 두번째 위치의 데이터를 교환
funswapData(fromPos:Int,toPos:Int){Collections.swap(dataSet,fromPos,toPos)notifyItemMoved(fromPos,toPos)}// 선택한 ViewHolder 포지션의 데이터 내용을 바꾸도록 함
funsetData(position:Int){dataSet[position]=listOf("main viewholder touched!","sub viewholder touched!")notifyItemChanged(position)}}
스와이프와 드래그 기능 붙이기
안드로이드에서는 Recyclerview에 입력되는 스와이프와 드래그 동작을 감지하는 ItemTouchHelper.SimpleCallback 클래스가 이미 준비되어 있으니 이걸 사용하겠습니다. 이 콜백함수는 다음과 같이 정의하면 됩니다.
초기화할때 인식할 드래그 방향을 dragDirs, 스와이프 방향을 swipeDirs로 정해주는데 여기서는 드래그 방향은 위, 아래. 그리고 스와이프 방향은 왼쪽만 인식하도록 하였습니다.
onSwiped에서는 스와이프가 일어날 때 데이터를 삭제하는 동작을 정의합니다. 터치한 ViewHolder 위치를 어댑터에 전달하여 removeData를 실행합니다.
onMove에서는 드래그가 일어날 때 두 ViewHolder의 데이터를 교환하는 동작을 정의합니다. 드래그가 시작되었을 때 ViewHolder의 위치와 이동이 완료된 후의 ViewHolder의 위치를 각각 fromPos, toPos로 정의하고 swapData에 넘겨주어 데이터를 교환하게 합니다. 이때 스크롤 동작과 헷갈리지 않게 하기 위해서 ViewHolder를 드래그하기 위해서는 롱터치를 해야 합니다.
이때 onSwiped에서는 layoutPosition을 사용했고, onMove에서는 adapterPosition을 사용했습니다. 스와이프를 할 때 ViewHolder의 위치는 고정되어 있지만 드래그를 할때는 ViewHolder의 위치가 계속 변하게 됩니다. adapterPosition은 전체 Recyclerview 안에서 위치를 가져오는 속성이고 layoutPosition은 고정된 ViewHolder의 위치를 가져오는 속성입니다.
ViewHolder에 드래그 가능 여부를 알리는 이미지 표시
현재는 ViewHolder가 데이터만 표시되고 있어서 이 ViewHolder를 드래그 할수 있는지 바로 알수 있는 방법이 없습니다. 그래서 ViewHolder 오른쪽에 햄버거 마크를 넣어서 드래그 할 수 있는 ViewHolder라는 표시를 해 주도록 하겠습니다.
다음으로 스와이프를 할때 미끄러져 나간 ViewHolder 아래에 Canvas 클래스를 이용해 작성한 빨간색 비트맵 이미지와 휴지통 아이콘을 표시되도록 하겠습니다. 이것을 위해서는 ItemTouchHelper.SimpleCallback의 onChildDraw를 사용합니다.
그리고 클릭 리스너를 붙여서 Snackbar로 터치한 위치를 보여주고 setData 함수가 실행되도록 합니다. 이때 setData는 Recyclerview 안의 함수이므로 ViewHolder 클래스에서 접근을 할 수가 없습니다. 그래서 ViewHolder를 inner classs로 변경하여줍니다.
현재는 ViewHolder를 터치했을 때 내용이 바뀌도록 하긴 했지만 정확히 어떤 ViewHolder를 터치한건지에 대한 표시가 나타나지 않습니다. 하지만 xml에 selectableItemBackground 속성을 정의하면 터치한 ViewHolder를 주목시키는 효과를 추가할 수 있습니다.