当前位置:   article > 正文

RecycleView拖动效果_可拖拽的recycview

可拖拽的recycview

前言:基于RecycleView实现拖动效果,其实很简单,只需使用系统提供的ItemTouchHelper即可满足大部分需求。

实现:

1、创建ItemTouchHelper,在CallBack中处理业务

(1)getMovementFlags()设置允许拖动、滑动的方向

(2)onMove()拖动过程不断调用,用于交换item

(3)onSelectedChanged()长按选中回调,可以用作选中背景高亮

(4)clearView()结束拖动回调,可以用作还原选中背景

2、关联RecycleView,赋予滑动能力

  1. override fun onCreate(savedInstanceState: Bundle?) {
  2. super.onCreate(savedInstanceState)
  3. setContentView(R.layout.activity_main)
  4. val tableList = ArrayList<String>()
  5. for (i in 1..200) {
  6. tableList.add("桌(${i})")
  7. }
  8. rv_table.layoutManager = GridLayoutManager(this, 5)
  9. TableAdapter().let {
  10. it.mTableList = tableList
  11. rv_table.adapter = it
  12. }
  13. val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() {
  14. override fun getMovementFlags(
  15. recyclerView: RecyclerView,
  16. viewHolder: RecyclerView.ViewHolder
  17. ): Int {
  18. //拖动方向
  19. val dargFlags =
  20. ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT or ItemTouchHelper.UP or ItemTouchHelper.DOWN
  21. //滑动方向
  22. val swipeFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
  23. //设置拖动、滑动方向
  24. return makeMovementFlags(dargFlags, swipeFlags)
  25. }
  26. override fun onMove(
  27. recyclerView: RecyclerView,
  28. viewHolder: RecyclerView.ViewHolder,
  29. target: RecyclerView.ViewHolder
  30. ): Boolean {
  31. //拖动的ViewHolder位置
  32. val fromPosition = viewHolder.adapterPosition
  33. //经过的ViewHolder位置
  34. val toPosition = target.adapterPosition
  35. when{
  36. fromPosition < toPosition -> {//向后拖动,和位置+1进行交换
  37. for (i in fromPosition..toPosition) {
  38. Collections.swap(tableList, i, i + 1)
  39. }
  40. recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
  41. }
  42. fromPosition > toPosition -> {//向前拖动,和位置-1进行交换
  43. for (i in fromPosition..toPosition) {
  44. Collections.swap(tableList, i, i - 1)
  45. }
  46. recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
  47. }
  48. }
  49. return true
  50. }
  51. override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
  52. super.onSelectedChanged(viewHolder, actionState)
  53. //长按选中更新要拖动的ViewHolder背景色
  54. (viewHolder as? TableAdapter.TableViewHolder)?.tvTabe?.setBackgroundResource(R.color.colorPrimary)
  55. }
  56. override fun clearView(
  57. recyclerView: RecyclerView,
  58. viewHolder: RecyclerView.ViewHolder
  59. ) {
  60. super.clearView(recyclerView, viewHolder)
  61. (viewHolder as TableAdapter.TableViewHolder).tvTabe.setBackgroundResource(R.color.colorAccent)
  62. }
  63. override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
  64. })
  65. //赋予RecycleView拖动能力
  66. itemTouchHelper.attachToRecyclerView(rv_table)
  67. }

进阶

场景一:禁止部分item拖动(如第1项禁止拖动)

1、禁用默认的拖动:CallBack中isLongPressDragEnabled()返回false

2、在自定义实现的item长按事件里,对于满足条件的执行拖动操作

  1. override fun onCreate(savedInstanceState: Bundle?) {
  2. super.onCreate(savedInstanceState)
  3. setContentView(R.layout.activity_main)
  4. val tableList = ArrayList<String>()
  5. for (i in 1..200) {
  6. tableList.add("桌(${i})")
  7. }
  8. rv_table.layoutManager = GridLayoutManager(this, 5)
  9. val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() {
  10. override fun getMovementFlags(
  11. recyclerView: RecyclerView,
  12. viewHolder: RecyclerView.ViewHolder
  13. ): Int {
  14. //拖动方向
  15. val dargFlags =
  16. ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT or ItemTouchHelper.UP or ItemTouchHelper.DOWN
  17. //滑动方向
  18. val swipeFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
  19. //设置拖动、滑动方向
  20. return makeMovementFlags(dargFlags, swipeFlags)
  21. }
  22. override fun onMove(
  23. recyclerView: RecyclerView,
  24. viewHolder: RecyclerView.ViewHolder,
  25. target: RecyclerView.ViewHolder
  26. ): Boolean {
  27. //拖动的ViewHolder位置
  28. val fromPosition = viewHolder.adapterPosition
  29. //经过的ViewHolder位置
  30. val toPosition = target.adapterPosition
  31. when{
  32. fromPosition < toPosition -> {//向后拖动,和位置+1进行交换
  33. for (i in fromPosition..toPosition) {
  34. Collections.swap(tableList, i, i + 1)
  35. }
  36. recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
  37. }
  38. fromPosition > toPosition -> {//向前拖动,和位置-1进行交换
  39. for (i in fromPosition..toPosition) {
  40. Collections.swap(tableList, i, i - 1)
  41. }
  42. recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
  43. }
  44. }
  45. return true
  46. }
  47. override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
  48. super.onSelectedChanged(viewHolder, actionState)
  49. //长按选中更新要拖动的ViewHolder背景色
  50. (viewHolder as? TableAdapter.TableViewHolder)?.tvTabe?.setBackgroundResource(R.color.colorPrimary)
  51. }
  52. override fun clearView(
  53. recyclerView: RecyclerView,
  54. viewHolder: RecyclerView.ViewHolder
  55. ) {
  56. super.clearView(recyclerView, viewHolder)
  57. (viewHolder as TableAdapter.TableViewHolder).tvTabe.setBackgroundResource(R.color.colorAccent)
  58. }
  59. override fun isLongPressDragEnabled(): Boolean {
  60. //禁用默认拖动
  61. return false
  62. }
  63. override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
  64. })
  65. //赋予RecycleView滑动能力
  66. itemTouchHelper.attachToRecyclerView(rv_table)
  67. TableAdapter().let {
  68. it.mTableList = tableList
  69. rv_table.adapter = it
  70. //将拖动职能传递给Adapter
  71. it.mItemTouchHelper = itemTouchHelper
  72. }
  73. }

  1. class TableAdapter : RecyclerView.Adapter<TableAdapter.TableViewHolder>(){
  2. var mTableList = ArrayList<String>()
  3. var mItemTouchHelper: ItemTouchHelper? = null
  4. override fun getItemCount(): Int {
  5. return mTableList.size
  6. }
  7. override fun onBindViewHolder(holder: TableViewHolder, position: Int) {
  8. val table = mTableList[position]
  9. holder.tvTabe.text = table
  10. }
  11. override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TableViewHolder {
  12. val view = LayoutInflater.from(parent.context).inflate(R.layout.item_table, parent, false)
  13. return TableViewHolder(view)
  14. }
  15. inner class TableViewHolder constructor(view: View): RecyclerView.ViewHolder(view) {
  16. val tvTabe = view.findViewById<TextView>(R.id.tv_table)
  17. init {
  18. tvTabe.setOnLongClickListener {
  19. if (this.adapterPosition != 0){
  20. mItemTouchHelper?.startDrag(this)
  21. return@setOnLongClickListener true
  22. }
  23. return@setOnLongClickListener false
  24. }
  25. }
  26. }
  27. }

场景二:只需将拖动的item和最终位置item进行交换,途径位置保持不变

1、在onMove()中将经过的位置记录到拖动的ViewHolder中

2、在clearView()中进行位置交换

  1. override fun onCreate(savedInstanceState: Bundle?) {
  2. super.onCreate(savedInstanceState)
  3. setContentView(R.layout.activity_main)
  4. val tableList = ArrayList<String>()
  5. for (i in 1..200) {
  6. tableList.add("桌(${i})")
  7. }
  8. rv_table.layoutManager = GridLayoutManager(this, 5)
  9. val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() {
  10. override fun getMovementFlags(
  11. recyclerView: RecyclerView,
  12. viewHolder: RecyclerView.ViewHolder
  13. ): Int {
  14. //拖动方向
  15. val dargFlags =
  16. ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT or ItemTouchHelper.UP or ItemTouchHelper.DOWN
  17. //滑动方向
  18. val swipeFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
  19. //设置拖动、滑动方向
  20. return makeMovementFlags(dargFlags, swipeFlags)
  21. }
  22. override fun onMove(
  23. recyclerView: RecyclerView,
  24. viewHolder: RecyclerView.ViewHolder,
  25. target: RecyclerView.ViewHolder
  26. ): Boolean {
  27. //经过的ViewHolder位置保存到拖动的ViewHolder中
  28. val toPosition = target.adapterPosition
  29. (viewHolder as TableAdapter.TableViewHolder).toPosition = toPosition
  30. return true
  31. }
  32. override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
  33. super.onSelectedChanged(viewHolder, actionState)
  34. //长按选中更新要拖动的ViewHolder背景色
  35. (viewHolder as? TableAdapter.TableViewHolder)?.tvTabe?.setBackgroundResource(R.color.colorPrimary)
  36. }
  37. override fun clearView(
  38. recyclerView: RecyclerView,
  39. viewHolder: RecyclerView.ViewHolder
  40. ) {
  41. super.clearView(recyclerView, viewHolder)
  42. (viewHolder as TableAdapter.TableViewHolder).tvTabe.setBackgroundResource(R.color.colorAccent)
  43. //拖动ViewHolder位置
  44. val fromPosition = viewHolder.adapterPosition
  45. //终点位置
  46. val toPosition = viewHolder.toPosition
  47. if (toPosition >= 0){
  48. Collections.swap(tableList, fromPosition, toPosition)
  49. recyclerView.adapter?.let{
  50. it.notifyItemChanged(fromPosition)
  51. it.notifyItemChanged(toPosition)
  52. }
  53. }
  54. }
  55. override fun isLongPressDragEnabled(): Boolean {
  56. //禁用默认拖动
  57. return false
  58. }
  59. override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
  60. })
  61. //赋予RecycleView滑动能力
  62. itemTouchHelper.attachToRecyclerView(rv_table)
  63. TableAdapter().let {
  64. it.mTableList = tableList
  65. rv_table.adapter = it
  66. //将拖动职能传递给Adapter
  67. it.mItemTouchHelper = itemTouchHelper
  68. }
  69. }
  1. class TableAdapter : RecyclerView.Adapter<TableAdapter.TableViewHolder>(){
  2. var mTableList = ArrayList<String>()
  3. var mItemTouchHelper: ItemTouchHelper? = null
  4. override fun getItemCount(): Int {
  5. return mTableList.size
  6. }
  7. override fun onBindViewHolder(holder: TableViewHolder, position: Int) {
  8. val table = mTableList[position]
  9. holder.tvTabe.text = table
  10. }
  11. override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TableViewHolder {
  12. val view = LayoutInflater.from(parent.context).inflate(R.layout.item_table, parent, false)
  13. return TableViewHolder(view)
  14. }
  15. inner class TableViewHolder constructor(view: View): RecyclerView.ViewHolder(view) {
  16. val tvTabe = view.findViewById<TextView>(R.id.tv_table)
  17. var toPosition = -1
  18. init {
  19. tvTabe.setOnLongClickListener {
  20. if (this.adapterPosition != 0){
  21. mItemTouchHelper?.startDrag(this)
  22. return@setOnLongClickListener true
  23. }
  24. return@setOnLongClickListener false
  25. }
  26. }
  27. }
  28. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/286798
推荐阅读
  

闽ICP备14008679号