recycleview出现已经很久了,拖拽以及滑动删除也很成熟了,实现方法也有很多,这次主要通过实现ItemTouchHelper来实现的
我不知道简书怎么上传录屏 尴尬。。
先贴代码吧
因为这个demo是在公司项目上写的,所以一些基类就不贴了,不影响阅读
拖拽辅助类
package com.gtxc.momiwow.Utils
import android.graphics.Canvas
import android.graphics.Color
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.LogUtils
/**
* https://www.jianshu.com/p/8dec938d5ef8
*/
class ItemTouchHelperCallback(val listener: DragLister) : ItemTouchHelper.Callback() {
interface DragLister{
fun onDragMoveSwap(adapterPosition: Int, adapterPosition1: Int):Boolean
fun onSwipeDelete(adapterPosition: Int):Boolean
}
interface StartDragListener {
/**
* 该接口用于需要主动回调拖拽效果的
* @param viewHolder
*/
fun onStartDrag(viewHolder: RecyclerView.ViewHolder?)
}
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
val dragflag =ItemTouchHelper.UP or ItemTouchHelper.DOWN
val swipFlag =ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
val flag = makeMovementFlags(dragflag,swipFlag)
return flag
}
override fun isLongPressDragEnabled(): Boolean {
return true
}
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
val result = listener.onDragMoveSwap(viewHolder.adapterPosition,target.adapterPosition)
return result
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
LogUtils.e("onSwiped")
listener.onSwipeDelete(viewHolder.adapterPosition)
}
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
if(actionState==ItemTouchHelper.ACTION_STATE_IDLE) return
viewHolder?.itemView?.setBackgroundColor(Color.GRAY)
super.onSelectedChanged(viewHolder, actionState)
}
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
super.clearView(recyclerView, viewHolder)
viewHolder?.itemView?.setBackgroundColor(Color.WHITE)
viewHolder.itemView?.apply {
alpha=1F
scaleX=1F
scaleY= 1F
}
}
override fun onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
if(actionState==ItemTouchHelper.ACTION_STATE_SWIPE){
val value = 1-Math.abs(dX)/viewHolder.itemView.width
viewHolder.itemView.apply {
alpha=value
scaleY=value
scaleX=value
}
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
}
}
adapter
package com.gtxc.momiwow.ui.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.LogUtils
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.gtxc.momiwow.R
import com.gtxc.momiwow.Utils.GlideUtils
import com.gtxc.momiwow.Utils.ItemTouchHelperCallback
import com.ksck.logoDesign.app.data.Detail
import com.youth.banner.adapter.BannerAdapter
import org.w3c.dom.Text
import java.util.*
/**
* 自定义布局,下面是常见的图片样式,更多实现可以看demo,可以自己随意发挥
*/
class DragAdapter() : BaseQuickAdapter<String, BaseViewHolder>(R.layout.item_drag),
ItemTouchHelperCallback.DragLister {
override fun convert(holder: BaseViewHolder?, item: String?) {
val imageView = holder?.getView<ImageView>(R.id.ivBanners)
holder?.setText(R.id.tvPosition,""+holder.layoutPosition)
item?.let {
if (imageView != null) {
GlideUtils.loadImages(imageView, it)
}
}
}
override fun onDragMoveSwap(adapterPosition: Int, adapterPosition1: Int): Boolean {
Collections.swap(data, adapterPosition, adapterPosition1);
notifyItemMoved(adapterPosition, adapterPosition1);
LogUtils.e("onDragMoveSwap")
return true
}
override fun onSwipeDelete(adapterPosition: Int):Boolean {
LogUtils.e("onSwipeDelete")
data.removeAt(adapterPosition)
notifyItemRemoved(adapterPosition)
return true
}
}
activity
package com.gtxc.momiwow.ui
import android.os.Bundle
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.aleyn.mvvm.base.NoViewModel
import com.blankj.utilcode.util.LogUtils
import com.chad.library.adapter.base.listener.OnItemDragListener
import com.gtxc.momiwow.R
import com.gtxc.momiwow.Utils.ItemTouchHelperCallback
import com.gtxc.momiwow.Utils.clickDelay
import com.gtxc.momiwow.base.CommonBaseActivity
import com.gtxc.momiwow.ui.adapter.DragAdapter
import com.gtxc.momiwow.ui.adapter.ImageAdapter
import com.youth.banner.adapter.BannerAdapter
import kotlinx.android.synthetic.main.activity_drag.*
import java.util.*
class DragActivity : CommonBaseActivity<NoViewModel, ViewDataBinding>(),
ItemTouchHelperCallback.StartDragListener {
val bannerAdapter by lazy {
DragAdapter()
}
val list = mutableListOf<String>(
//图片地址
)
lateinit var itemTouchHelper: ItemTouchHelper
override fun layoutId(): Int {
return R.layout.activity_drag
}
override fun initView(savedInstanceState: Bundle?) {
super.initView(savedInstanceState)
}
override fun initData() {
reset.clickDelay {
list.addAll(
mutableListOf<String>(
//图片地址
)
)
bannerAdapter.setNewData(list)
}
recycler.layoutManager = LinearLayoutManager(this)
recycler.adapter = bannerAdapter
bannerAdapter.setNewData(
list
)
val callback = ItemTouchHelperCallback(bannerAdapter)
itemTouchHelper = ItemTouchHelper(callback)
itemTouchHelper.attachToRecyclerView(recycler)
}
override fun initCLick() {
}
override fun bindViewModel() {
}
override fun onStartDrag(viewHolder: RecyclerView.ViewHolder?) {
if (viewHolder != null) {
itemTouchHelper.startDrag(viewHolder)
}
}
}
但是这个有个问题 如果gridlayoutmanager的话 横向删除和拖拽就无效了,后续会看看网上其他方案是怎么解决的
Gridlayoutmanager代码
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
val layoutManager =
recyclerView.layoutManager
var dragFlags = 0
var swipeFlags = 0
if (layoutManager is GridLayoutManager) {
// 如果是Grid布局,则不能滑动,只能上下左右拖动
dragFlags =
ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
swipeFlags = 0
} else if (layoutManager is LinearLayoutManager) {
// 如果是纵向Linear布局,则能上下拖动,左右滑动
if ((layoutManager as LinearLayoutManager?)?.orientation === LinearLayoutManager.VERTICAL) {
dragFlags =
ItemTouchHelper.UP or ItemTouchHelper.DOWN
swipeFlags =
ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
} else {
// 如果是横向Linear布局,则能左右拖动,上下滑动
swipeFlags =
ItemTouchHelper.UP or ItemTouchHelper.DOWN
dragFlags =
ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
}
}
return makeMovementFlags(
dragFlags,
swipeFlags
)
}