짜잔!
간단하게 구현한 결과 화면부터 감상하시죠
자 오늘은 RecyclerView의 Drag&Drop / Swipe 기능을 알아보겠습니다.
RecyclerView에 대한 내용은 아래의 내용을 참고해주세요!
[Android] Kotlin RecyclerView 알아보기
이름에서 알 수 있듯이 RecyclerView는 이러한 개별 요소를 재활용합니다. 항목이 스크롤되어 화면에서 벗어나더라도 RecyclerView는 뷰를 제거하지 않습니다. 대신 RecyclerView는 화면에서 스크롤된 새
salmonpack.tistory.com
우선 위와 같은 기능 구현을 하기 위한 준비 단계를 알아보겠습니다.
- RecyclerView / RecyclerView Adapter 구현
- ItemTouchHelper Callback 구현
- RecyclerView Adapter에서 Interface 적용하여 사용
RecycleView와 Adapter는 구현되어 있다고 가정하겠습니다.
그러면 우선 Class를 하나 구현하여
ItemTouchHelper Callback의
- getMovementFlags()
- onMove()
- onSwiped()
- isLongPressDragEnabled()
- isItemViewSwipeEnabled()
메서드들을 overried 하여 구현합니다.
interface ItemTouchHelperListener {
fun onItemMove(formPosition: Int, toPosition: Int): Boolean
fun onItemSwipe(position: Int)
}
class ItemTouchHelperCallback(
val listener: ItemTouchHelperListener
): ItemTouchHelper.Callback() {
private var itemTouchHelperListener: ItemTouchHelperListener = listener
override fun isLongPressDragEnabled(): Boolean {
return true
}
override fun isItemViewSwipeEnabled(): Boolean {
return true
}
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
val swipeFlags = ItemTouchHelper.START or ItemTouchHelper.END
return makeMovementFlags(dragFlags, swipeFlags)
}
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
itemTouchHelperListener.onItemMove(
viewHolder.adapterPosition,
target.adapterPosition
)
return true
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
itemTouchHelperListener.onItemSwipe(viewHolder.adapterPosition)
}
}
getMovementFlags에서 drag의 방향 또는 swipe의 방향에 대한 값을
입력하여 makeMovementFlags에서 Int값으로 변환받습니다.
여기서 drag 또는 swipe 중 하나의 기능만 구현한다면
- Drag - return makeMovementFlags(dragFlags, 0) + onMove()
- Swipe - return makeMovementFlags(0, swipeFlags) + onSwiped()
이렇게 구현해주시면 될 것 같습니다.
다음은 RecyclerView Adpater에서 위에서 구현한 ItemTouchHelperListener 인터페이스를 상속받아
onItemMove() , onItemSwipe()를 override 하여 구현합니다.
class RecyclerViewAdapter(
private val list: MutableList<ItemData>
): RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder>(),
ItemTouchHelperListener {
...
override fun onItemMove(formPosition: Int, toPosition: Int): Boolean {
val formItem: ItemData = itemLists[formPosition]
val toItem: ItemData = itemLists[toPosition]
itemLists[formPosition] = toItem
itemLists[toPosition] = formItem
notifyItemMoved(formPosition,toPosition);
return true
}
override fun onItemSwipe(position: Int) {
itemLists.removeAt(position)
notifyItemRemoved(position)
}
...
}
notifyItemMoved() , notfyItemRemoved() 관련하여
아래 내용을 참조하여 주시고
[Android] RecyclerView 깜빡이는 현상 해결 (notifyDataSetChanged)
혹시 RecyclerView를 사용하면서 RecyclerView의 데이터 삭제 또는 추가 과정에서 RecyclerView가 깜빡이는 현상 때문에 고생하셨나요?? via GIPHY 위와 같은 현상에 대해서 알아보도록 하겠습니다. [Android] Kot
salmonpack.tistory.com
여기서 설명드린 RecyclerView onHasStabled() 메서드와 getItemId()를 구현하면,
위의 ItemToucherHelper의 동작이 정상 작동하지 않는 이슈를 발견했습니다.
setHasStableIds(true)
override fun getItemId(position: Int): Long {
return position.toLong()
}
// 두 가지를 구현했을 경우 ItemTouchHelper 구현이 정상적이지 않음
정확한 원인은 모르겠지만...
ItemTouchHelper getMovementFlags 동작 관련하여
내부적으로 item의 위치 이동 또는 삭제 시
item의 id 값을 이용하여 동작하는데,
setHasStabledIds / getItemId 값을 이용하여
item 값의 id를 기존과 다르게 사용하여 생기는 문제가 아닌가...
(혹시나 정확한 이유를 아신다면 댓글로 저의 부족한 지식을 채워 주세요...)
마지막입니다.
ItemToucheHelper에 구현한 Adapter와 RecyclerView를 연결시켜주면 됩니다.
rvAdapter = RecyclerViewAdapter(list)
binding.rvEx.adapter = rvAdapter
ItemTouchHelper(ItemTouchHelperCallback(rvAdapter)).apply {
attachToRecyclerView(binding.rvEx)
}
여기까지 저의 긴 글을 읽어주셔서 감사합니다.
제가 습관적으로 코딩을 하는 그날까지 습관적으로 코딩을 하기 위해 글 작성을 꾸준하게 해보겠습니다.
'Android > 스터디 노트' 카테고리의 다른 글
[Android] Android Debug Mode 잘 활용하기 (안드로이드 스튜디오 디버깅). (2) | 2022.10.12 |
---|---|
Clean Code - 주석 어떻게 사용하고 있나요? (0) | 2022.08.31 |
[Android] RecyclerView 깜빡이는 현상 해결 (notifyDataSetChanged) (0) | 2022.08.17 |
[Android] Kotlin RecyclerView 알아보기 (0) | 2022.08.17 |
[Google Play Store] 구글 테스트 계정의 모든것, 구글심사 테스트 계정, 인앱결제 테스트 계정 (4) | 2022.07.25 |
최근댓글