프로그램/Android

안드로이드 드래그앤 드롭(drag&drop) 사용법

잡식성초보 2020. 7. 3. 13:57

안드로이드 리사이클러뷰의 아이템을 클릭하여 옮기는, 순서를 바꾸는 기능에 대한 설명입니다.(드래그앤 드롭)

 

일단 기본적인 구조로 리사이클러뷰를 만드신 뒤 아이템을 추가합니다.

 

그리고 ItemTouchHelper.Callback 을 상속받는 클래스를 생성해야합니다.

 

클래스를 만들고 상속 받았을경우 필수로 사용해야하는 override 메소드는 getMovementFlags, onMove, onSwiped

 

3가지 입니다.

 

getMovementFlags 에서는 리사이클러뷰 아이템을 움직일 방향을 설정합니다.

 

onMove 에서는 아이템을 움직였을경우 순서를 바꿔주면 됩니다.

 

onSwiped 는 위아래로만 움직이는 기능이므로 사용을 하지 않습니다.

 

isLongPressDragEnabled, isItemViewSwipeEnabled 두가지 메소드도 override 하여 리턴값을 true와 false로 변경해야 합니다.

 

 

설명은 위와 같습니다. 기능을 구현하면서 별도로 필요했던 기능은 순서를 바꾼 뒤 그 순서를 서버로 전달하는 기능이 필요 하였습니다.

 

하지만 위에서 오버라이드하여 받은 메소드 어디에도 클릭하여 드래그앤드롭으로 순서를 변경뒤 터치를 종료하는 시점을 알 수가

 

없었습니다.(onMove는 아이템이 하나 바뀔대마다 들어옴)

 

그래서 모든 메소드를 체크 하여 onMoved, onSelectedChanged 를 이용하여 개발을 진행 할 수가 있었습니다.

 

클릭에 대한 boolean값을 하나 가지고 onMoved, onSelectedChanged 이용하면 되겠습니다.

 

 

ItemMoveCallback.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class ItemMoveCallback constructor(val adapter : Adapter) : ItemTouchHelper.Callback(){
 
    private var isMoved = false    //무빙 이벤트에 대한 boolean값
 
    override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
        val flagDrag = ItemTouchHelper.UP or ItemTouchHelper.DOWN    //드래그앤 드롭 움직임 설정
        return makeMovementFlags(flagDrag, 0)
    }
 
    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
        adapter.onItemDragMove(viewHolder.adapterPosition, target.adapterPosition)
        return true
    }
 
    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
 
    }
 
    override fun isLongPressDragEnabled(): Boolean {
        return true
    }
 
    override fun isItemViewSwipeEnabled(): Boolean {
        return false
    }
 
    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
        super.onSelectedChanged(viewHolder, actionState)
        if(isMoved){
            isMoved = false
            adapter.changeMoveEvent()
        }
    }
 
    override fun onMoved(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder,
        fromPos: Int,
        target: RecyclerView.ViewHolder,
        toPos: Int,
        x: Int,
        y: Int
    ) {
        super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
        isMoved = true
    }
}
cs

 

Adapter.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
    //arrayList 는 어뎁터에서 사용하고 있는 List, 순서를 변경하는 함수
    fun onItemDragMove(beforePosition : Int, afterPosition : Int){
        if(beforePosition < afterPosition){
            for (i in beforePosition until afterPosition) {
                Collections.swap(arrayList, i, i + 1)
            }
        } else {
            for (i in beforePosition downTo afterPosition + 1) {
                Collections.swap(arrayList, i, i - 1)
            }
        }
 
        notifyItemMoved(beforePosition, afterPosition)
    }
 
    //드래그앤 드롭 터치를 마무리 하였을 경우 들어오는 함수
    fun changeMoveEvent(){
 
    }
 
 
cs

 

 

 

Activity or Fragment

1
2
3
val callback = ItemMoveCallback(viewModel.adapter)
val touchHelper = ItemTouchHelper(callback)
touchHelper.attachToRecyclerView(binding.rvManage)    //리사이클러뷰를 넣어준다
cs

 

 

recrecyclerview drag&drop

반응형