2020-08-10에 업데이트 되었습니다.

 

설명(Recyclerview drag and drop)


recyclerview drag and drop 예제 코드(kotlin)에 대해서 포스팅하려고 합니다. recyclerview를 사용하실 때 recyclerview에 있는 아이템들을 드래그 앤 드롭으로 자리를 이동하는 방법에 대해서 개인적인 포스팅을 해보려고 합니다.

 

방법


1. app/build.gradle에 다음 코드를 추가합니다.

implementation 'androidx.recyclerview:recyclerview:1.1.0'

 

2. RecyclerView 어댑터와 item_recycclerview.xml 파일을 만듭니다.
RecyclerviewAdapter.kt

class RecyclerviewAdapter(private val startDragListener: OnStartDragListener) :
    RecyclerView.Adapter<RecyclerviewAdapter.ItemViewHolder>(),
    ItemMoveCallbackListener.Listener {

    private var users = emptyList<String>().toMutableList()
    fun setUsers(newUsers: List<String>) {
        users.addAll(newUsers)
    }
    override fun getItemCount(): Int {
        return users.size
    }
    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
        val user = users[position]
        holder.bind(user)
        holder.itemView.imageView.setOnTouchListener { _, event ->
            if (event.action == MotionEvent.ACTION_DOWN) {
                this.startDragListener.onStartDrag(holder)
            }
            return@setOnTouchListener true
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
        val itemView = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_recyclerview, parent, false)
        return ItemViewHolder(itemView)
    }

    class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(text: String) {
            itemView.textView.text = text
        }
    }

    override fun onRowMoved(fromPosition: Int, toPosition: Int) {
        if (fromPosition < toPosition) {
            for (i in fromPosition until toPosition) {
                Collections.swap(users, i, i + 1)
            }
        } else {
            for (i in fromPosition downTo toPosition + 1) {
                Collections.swap(users, i, i - 1)
            }
        }
        notifyItemMoved(fromPosition, toPosition)
    }

    override fun onRowSelected(itemViewHolder: ItemViewHolder) {
    }
    
    override fun onRowClear(itemViewHolder: ItemViewHolder) {
    }
}

 

item_recycclerview.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:background="#F7EEEE"
    android:layout_margin="8dp">

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:text="Drag and Drop Recycler View example"
        android:textSize="18sp"
        app:fontFamily="sans-serif-medium"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/imageView"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_drag_handle"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 

item_recyclerview.xml 에 있는 drawable/ic_drag_handle은
제가 임의로 넣은 이미지입니다.
저는 res -> drawable 에서 마우스 오른쪽을 누르고 new -> image Assset
들어가서 clip Art에서 drag handle라는 이미지를 만들어서 사용했습니다.

3. ItemMoveCallBackListener 클래스를 만듭니다.
ItemMoveCallBackListener.kt

class ItemMoveCallbackListener(val adapter: RecyclerviewAdapter) : ItemTouchHelper.Callback() {
    override fun getMovementFlags(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder
    ): Int {
        val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
        return makeMovementFlags(dragFlags, 0)
    }
    override fun isItemViewSwipeEnabled(): Boolean {
        return false
    }
    override fun isLongPressDragEnabled(): Boolean {
        return false
    }
    override fun onMove(
        recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder,
        target: RecyclerView.ViewHolder
    ): Boolean {
        adapter.onRowMoved(viewHolder.adapterPosition, target.adapterPosition)
        return true
    }
    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            if (viewHolder is RecyclerviewAdapter.ItemViewHolder) {
                adapter.onRowSelected(viewHolder)
            }
        }
        super.onSelectedChanged(viewHolder, actionState)
    }
    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
        super.clearView(recyclerView, viewHolder)
        if (viewHolder is RecyclerviewAdapter.ItemViewHolder) {
            adapter.onRowClear(viewHolder)
        }
    }
    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
    }
    interface Listener {
        fun onRowMoved(fromPosition: Int, toPosition: Int)
        fun onRowSelected(itemViewHolder: RecyclerviewAdapter.ItemViewHolder)
        fun onRowClear(itemViewHolder: RecyclerviewAdapter.ItemViewHolder)
    }
}

 

4. activity_main.xml과 MainActivity 코드를 작성합니다.
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

MainActivity.kt

class MainActivity : AppCompatActivity(), OnStartDragListener {
    lateinit var adapter: RecyclerviewAdapter
    lateinit var touchHelper: ItemTouchHelper
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        adapter = RecyclerviewAdapter(this)
        populateListItem()
        val callback: ItemTouchHelper.Callback = ItemMoveCallbackListener(adapter)
        touchHelper = ItemTouchHelper(callback)
        touchHelper.attachToRecyclerView(recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = adapter
    }
    override fun onStartDrag(viewHolder: RecyclerView.ViewHolder) {
        touchHelper.startDrag(viewHolder)
    }
    private fun populateListItem() {
        val users = listOf(
            "도",
            "움",
            "이",
            "되",
            "셨",
            "으",
            "면",
            "깃",
            "허",
            "브",
            "에",
            "별",
            "좀",
            "부",
            "탁",
            "드",
            "립",
            "니",
            "다"
        )
        adapter.setUsers(users)
    }
}

 

5. 실행화면입니다.

빨간색 네모칸 이미지를 드래그 앤 드롭하면 원하시는 위치로 이동 시킬 수 있습니다.

 

마무리


이번 포스팅은 recyclerview에서 drag and drop할 수 있는 방법에 대해 포스팅합니다.

깃허브 주소 :  https://https://github.com/timinguniq/RecyclerviewDragAndDropExample에 파일 올려놨습니다.

 

제 블로그 사이트 주소 : https://niqrid2020.pe.kr/?cat=3

추천 안드로이드 블로그 주소 : https://gun0912.tistory.com

 

 

 

 

 

 

 

 

 

 

 

“recyclerview drag and drop 예제 코드(kotlin)”의 한가지 생각

댓글이 닫혀있습니다.