기억에서 희미해져가는 드래그 기능을 다시 한번 짜보았다.
아주 부드럽게 잘 되는 것 같다.
Activity
class DragActivity : AppCompatActivity() {
private lateinit var binding: ActivityDragBinding
private var animalDragAdapter: DragAdapter? = null
private val animalList = arrayListOf(
"쥐",
"소",
"호랑이",
"토끼",
"용",
"뱀",
"말",
"양",
"원숭이",
"닭",
"개",
"돼지"
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDragBinding.inflate(layoutInflater)
setContentView(binding.root)
animalDragAdapter = DragAdapter(animalList, binding.rvAnimal)
}
}
어댑터안에 모두 때려박아서 데이터와 어댑터 연결뿐인 액티비티...
(단순히 본인의 간편한 테스트를 위해 축소 작성된 코드)
Adapter
class DragAdapter(
private val items: ArrayList<String>,
private val dragRecyclerview: RecyclerView
) : RecyclerView.Adapter<DragAdapter.DragViewHolder>(){
// 리사이클러뷰 터치 헬퍼
private var itemDragHelper: ItemTouchHelper? = null
// 드래그 위치 변경 콜백리스너
private val helperCallback = DragHelperCallback { fromPos, toPos ->
Collections.swap(items, fromPos, toPos)
notifyItemMoved(fromPos, toPos)
Log.d("시작: $fromPos", "변경: $toPos")
Log.d("items", "$items")
true
}
init {
dragRecyclerview.adapter = this
itemDragHelper = ItemTouchHelper(helperCallback).apply {
attachToRecyclerView(dragRecyclerview)
}
}
@SuppressLint("ClickableViewAccessibility")
override fun onBindViewHolder(holder: DragViewHolder, position: Int) {
holder.viewDataBinding.run {
tvDrag.text = items[position]
// 드래그 이벤트 시작 (부드러운 사용을 위해 버튼 터치다운시 바로 드래그 시작)
ibDrag.setOnTouchListener { _, motionEvent ->
if (motionEvent.action == MotionEvent.ACTION_DOWN) {
itemDragHelper?.startDrag(holder)
}
return@setOnTouchListener false
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DragViewHolder {
return DragViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.item_drag, parent, false)
)
}
inner class DragViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val viewDataBinding = ItemDragBinding.bind(view)
}
override fun getItemCount(): Int = items.size
inner class DragHelperCallback(
private val actionDrag: (Int, Int) -> Boolean
) : ItemTouchHelper.Callback() {
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
// 상하 드래그시
val dragFlag = ItemTouchHelper.UP or ItemTouchHelper.DOWN
// 좌우 드래그시
// val dragFlag = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
return makeMovementFlags(dragFlag, 0)
}
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
// 시작 위치와 변경되는 위치 전달
return actionDrag.invoke(viewHolder.adapterPosition, target.adapterPosition)
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
// 사용x
override fun isLongPressDragEnabled(): Boolean = false
}
}
개인적으로 isLongPressDragEnabled를 사용하는 것 보다 낫다고 생각된다.
'안드로이드' 카테고리의 다른 글
[android] QR코드 스캔하기, 바코드 스캔하기 (0) | 2022.11.14 |
---|---|
[android] 구글 로그인 플레이스토어 업로드시 오류 (0) | 2022.11.10 |
[android] 그림자가 안생겨요. elevation not working. (0) | 2022.11.02 |
[android] INSTALL_PARSE_FAILED_MANIFEST_MALFORMED (0) | 2022.11.02 |
[android stuido] 개발앱, 운영앱 구분하기 (productFlavors) (0) | 2022.10.31 |
댓글