ItemTouchHelper打造可拖拽的卡片布局

这是效果android

Activity.onCreate()

首先咱们建立在Activity的onCreate()方法中git

val itemTouchHelper = ItemTouchHelper(touchHelperCallback)
itemTouchHelper.attachToRecyclerView(list)
复制代码

这里的touchHelperCallback是单例对象,继承自ItemTouchHelper.Callback()github

自定义ItemTouchHelper.Callback

须要实现几个方法ide

必须方法

getMovementFlags()

判断RecyclerView上的哪些方向操做交由ItemTouchHelper.Callback控制函数

此处咱们直接ui

override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
			//dragFlags
            return makeMovementFlags(ItemTouchHelper.UP
                                    or ItemTouchHelper.DOWN
                                    or ItemTouchHelper.LEFT
                                    or ItemTouchHelper.RIGHT,
           //swipeFlags 
            0
            )
        }
复制代码

onMove()

咱们从新排列viewModel的item顺序,viewModel将会经过LiveData实现UI的更新this

override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
            viewModel.move(viewHolder.adapterPosition, target.adapterPosition)
            return true
        }
复制代码

onSwiped()

因为没有swipe的操做,不作任何事情google

isItemViewSwipeEnabled()

默认为true,选择返回false,spa

isLongPressDragEnabled()

选择返回false,由于咱们想要手动处理长按操做,经过startDrag(ViewHolder)方法code

非必需方法

onSelectedChanged()

当item被选中的时候,须要进行的操做,一般能够加深view的elevation

clearView()

当item被取消选中的时候,须要进行的操做,一般将view的elevation设为正常值

长按拖动view

咱们在RecyclerView的adapter中传入一个函数

val adapter = CheeseGridAdapter(onItemLongClick = { holder ->
            itemTouchHelper.startDrag(holder)
        })
复制代码

而后在adapter内部的onCreateViewHolder()中添加监听器

itemView.setOnLongClickListener {
                onItemLongClick(this)
                true
            }
复制代码

这样就实现了长按拖动view

数据更新

如何实现当view拖动的时候,其他的item的位置也会跟着变化呢?

这说明它们的数据的位置变动了。

这种状况,若是咱们选择ListAdapter配合ViewModel,那么会减轻咱们的工做量

首先,咱们以前写的继承自ItemTouchHelper.Callback的类的onMove()方法中,咱们

viewModel.move(viewHolder.adapterPosition, target.adapterPosition)
复制代码

咱们看看这个move()方法作了什么

fun move(from: Int, to: Int) {
        _cheeses.value?.let { list ->
            val cheese = list.removeAt(from)
            list.add(to, cheese)
            _cheeses.value = list
        }
    }
复制代码

这里的_cheeses对象是咱们定义的MutableLiveData对象

这时候,若是咱们在onCreate()中observe

viewModel.cheeses.observe(this) { cheeses  ->

            adapter.submitList(cheeses)
        }
复制代码

因而就实现了数据的自动的刷新

本篇文章其实就是解读了一下google官方的sample,若是有什么理解不对的地方,但愿你们批评

最后贴上:

个人github实现

google官方sample

相关文章
相关标签/搜索