赞
踩
前言:基于RecycleView实现拖动效果,其实很简单,只需使用系统提供的ItemTouchHelper即可满足大部分需求。
实现:
1、创建ItemTouchHelper,在CallBack中处理业务
(1)getMovementFlags()设置允许拖动、滑动的方向
(2)onMove()拖动过程不断调用,用于交换item
(3)onSelectedChanged()长按选中回调,可以用作选中背景高亮
(4)clearView()结束拖动回调,可以用作还原选中背景
2、关联RecycleView,赋予滑动能力
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- val tableList = ArrayList<String>()
- for (i in 1..200) {
- tableList.add("桌(${i})")
- }
- rv_table.layoutManager = GridLayoutManager(this, 5)
- TableAdapter().let {
- it.mTableList = tableList
- rv_table.adapter = it
- }
- val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() {
- override fun getMovementFlags(
- recyclerView: RecyclerView,
- viewHolder: RecyclerView.ViewHolder
- ): Int {
- //拖动方向
- val dargFlags =
- ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT or ItemTouchHelper.UP or ItemTouchHelper.DOWN
- //滑动方向
- val swipeFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
- //设置拖动、滑动方向
- return makeMovementFlags(dargFlags, swipeFlags)
- }
-
- override fun onMove(
- recyclerView: RecyclerView,
- viewHolder: RecyclerView.ViewHolder,
- target: RecyclerView.ViewHolder
- ): Boolean {
- //拖动的ViewHolder位置
- val fromPosition = viewHolder.adapterPosition
- //经过的ViewHolder位置
- val toPosition = target.adapterPosition
- when{
- fromPosition < toPosition -> {//向后拖动,和位置+1进行交换
- for (i in fromPosition..toPosition) {
- Collections.swap(tableList, i, i + 1)
- }
- recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
- }
- fromPosition > toPosition -> {//向前拖动,和位置-1进行交换
- for (i in fromPosition..toPosition) {
- Collections.swap(tableList, i, i - 1)
- }
- recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
- }
- }
- return true
- }
-
- override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
- super.onSelectedChanged(viewHolder, actionState)
- //长按选中更新要拖动的ViewHolder背景色
- (viewHolder as? TableAdapter.TableViewHolder)?.tvTabe?.setBackgroundResource(R.color.colorPrimary)
- }
-
- override fun clearView(
- recyclerView: RecyclerView,
- viewHolder: RecyclerView.ViewHolder
- ) {
- super.clearView(recyclerView, viewHolder)
- (viewHolder as TableAdapter.TableViewHolder).tvTabe.setBackgroundResource(R.color.colorAccent)
- }
- override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
- })
- //赋予RecycleView拖动能力
- itemTouchHelper.attachToRecyclerView(rv_table)
- }
进阶
场景一:禁止部分item拖动(如第1项禁止拖动)
1、禁用默认的拖动:CallBack中isLongPressDragEnabled()返回false
2、在自定义实现的item长按事件里,对于满足条件的执行拖动操作
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- val tableList = ArrayList<String>()
- for (i in 1..200) {
- tableList.add("桌(${i})")
- }
- rv_table.layoutManager = GridLayoutManager(this, 5)
- val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() {
- override fun getMovementFlags(
- recyclerView: RecyclerView,
- viewHolder: RecyclerView.ViewHolder
- ): Int {
- //拖动方向
- val dargFlags =
- ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT or ItemTouchHelper.UP or ItemTouchHelper.DOWN
- //滑动方向
- val swipeFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
- //设置拖动、滑动方向
- return makeMovementFlags(dargFlags, swipeFlags)
- }
-
- override fun onMove(
- recyclerView: RecyclerView,
- viewHolder: RecyclerView.ViewHolder,
- target: RecyclerView.ViewHolder
- ): Boolean {
- //拖动的ViewHolder位置
- val fromPosition = viewHolder.adapterPosition
- //经过的ViewHolder位置
- val toPosition = target.adapterPosition
- when{
- fromPosition < toPosition -> {//向后拖动,和位置+1进行交换
- for (i in fromPosition..toPosition) {
- Collections.swap(tableList, i, i + 1)
- }
- recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
- }
- fromPosition > toPosition -> {//向前拖动,和位置-1进行交换
- for (i in fromPosition..toPosition) {
- Collections.swap(tableList, i, i - 1)
- }
- recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
- }
- }
- return true
- }
-
- override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
- super.onSelectedChanged(viewHolder, actionState)
- //长按选中更新要拖动的ViewHolder背景色
- (viewHolder as? TableAdapter.TableViewHolder)?.tvTabe?.setBackgroundResource(R.color.colorPrimary)
- }
-
- override fun clearView(
- recyclerView: RecyclerView,
- viewHolder: RecyclerView.ViewHolder
- ) {
- super.clearView(recyclerView, viewHolder)
- (viewHolder as TableAdapter.TableViewHolder).tvTabe.setBackgroundResource(R.color.colorAccent)
- }
-
- override fun isLongPressDragEnabled(): Boolean {
- //禁用默认拖动
- return false
- }
- override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
- })
- //赋予RecycleView滑动能力
- itemTouchHelper.attachToRecyclerView(rv_table)
- TableAdapter().let {
- it.mTableList = tableList
- rv_table.adapter = it
- //将拖动职能传递给Adapter
- it.mItemTouchHelper = itemTouchHelper
- }
- }
- class TableAdapter : RecyclerView.Adapter<TableAdapter.TableViewHolder>(){
- var mTableList = ArrayList<String>()
- var mItemTouchHelper: ItemTouchHelper? = null
-
- override fun getItemCount(): Int {
- return mTableList.size
- }
-
- override fun onBindViewHolder(holder: TableViewHolder, position: Int) {
- val table = mTableList[position]
- holder.tvTabe.text = table
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TableViewHolder {
- val view = LayoutInflater.from(parent.context).inflate(R.layout.item_table, parent, false)
- return TableViewHolder(view)
- }
-
- inner class TableViewHolder constructor(view: View): RecyclerView.ViewHolder(view) {
- val tvTabe = view.findViewById<TextView>(R.id.tv_table)
-
- init {
- tvTabe.setOnLongClickListener {
- if (this.adapterPosition != 0){
- mItemTouchHelper?.startDrag(this)
- return@setOnLongClickListener true
- }
- return@setOnLongClickListener false
- }
- }
- }
- }
场景二:只需将拖动的item和最终位置item进行交换,途径位置保持不变
1、在onMove()中将经过的位置记录到拖动的ViewHolder中
2、在clearView()中进行位置交换
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- val tableList = ArrayList<String>()
- for (i in 1..200) {
- tableList.add("桌(${i})")
- }
- rv_table.layoutManager = GridLayoutManager(this, 5)
- val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() {
- override fun getMovementFlags(
- recyclerView: RecyclerView,
- viewHolder: RecyclerView.ViewHolder
- ): Int {
- //拖动方向
- val dargFlags =
- ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT or ItemTouchHelper.UP or ItemTouchHelper.DOWN
- //滑动方向
- val swipeFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
- //设置拖动、滑动方向
- return makeMovementFlags(dargFlags, swipeFlags)
- }
-
- override fun onMove(
- recyclerView: RecyclerView,
- viewHolder: RecyclerView.ViewHolder,
- target: RecyclerView.ViewHolder
- ): Boolean {
- //经过的ViewHolder位置保存到拖动的ViewHolder中
- val toPosition = target.adapterPosition
- (viewHolder as TableAdapter.TableViewHolder).toPosition = toPosition
- return true
- }
-
- override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
- super.onSelectedChanged(viewHolder, actionState)
- //长按选中更新要拖动的ViewHolder背景色
- (viewHolder as? TableAdapter.TableViewHolder)?.tvTabe?.setBackgroundResource(R.color.colorPrimary)
- }
-
- override fun clearView(
- recyclerView: RecyclerView,
- viewHolder: RecyclerView.ViewHolder
- ) {
- super.clearView(recyclerView, viewHolder)
- (viewHolder as TableAdapter.TableViewHolder).tvTabe.setBackgroundResource(R.color.colorAccent)
- //拖动ViewHolder位置
- val fromPosition = viewHolder.adapterPosition
- //终点位置
- val toPosition = viewHolder.toPosition
- if (toPosition >= 0){
- Collections.swap(tableList, fromPosition, toPosition)
- recyclerView.adapter?.let{
- it.notifyItemChanged(fromPosition)
- it.notifyItemChanged(toPosition)
- }
- }
- }
-
- override fun isLongPressDragEnabled(): Boolean {
- //禁用默认拖动
- return false
- }
- override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
- })
- //赋予RecycleView滑动能力
- itemTouchHelper.attachToRecyclerView(rv_table)
- TableAdapter().let {
- it.mTableList = tableList
- rv_table.adapter = it
- //将拖动职能传递给Adapter
- it.mItemTouchHelper = itemTouchHelper
- }
- }
- class TableAdapter : RecyclerView.Adapter<TableAdapter.TableViewHolder>(){
- var mTableList = ArrayList<String>()
- var mItemTouchHelper: ItemTouchHelper? = null
-
- override fun getItemCount(): Int {
- return mTableList.size
- }
-
- override fun onBindViewHolder(holder: TableViewHolder, position: Int) {
- val table = mTableList[position]
- holder.tvTabe.text = table
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TableViewHolder {
- val view = LayoutInflater.from(parent.context).inflate(R.layout.item_table, parent, false)
- return TableViewHolder(view)
- }
-
- inner class TableViewHolder constructor(view: View): RecyclerView.ViewHolder(view) {
- val tvTabe = view.findViewById<TextView>(R.id.tv_table)
- var toPosition = -1
-
- init {
- tvTabe.setOnLongClickListener {
- if (this.adapterPosition != 0){
- mItemTouchHelper?.startDrag(this)
- return@setOnLongClickListener true
- }
- return@setOnLongClickListener false
- }
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。