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)”의 한가지 생각
댓글이 닫혀있습니다.