Skip to content

Commit a90f1b9

Browse files
committed
定义 SwipeDragHelper ,抽象回调接口;解耦 FlapAdapter
1 parent 09b166a commit a90f1b9

File tree

5 files changed

+182
-104
lines changed

5 files changed

+182
-104
lines changed

app/src/main/java/me/yifeiyuan/flapdev/testcases/BaseTestcaseFragment.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import androidx.recyclerview.widget.RecyclerView
1616
import androidx.recyclerview.widget.StaggeredGridLayoutManager
1717
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
1818
import me.yifeiyuan.flap.FlapAdapter
19-
import me.yifeiyuan.flap.ext.FlapItemTouchHelper
2019
import me.yifeiyuan.flap.decoration.LinearItemDecoration
2120
import me.yifeiyuan.flap.decoration.LinearSpaceItemDecoration
2221
import me.yifeiyuan.flap.decoration.SpaceItemDecoration

app/src/main/java/me/yifeiyuan/flapdev/testcases/SwipeAndDragTestcase.kt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package me.yifeiyuan.flapdev.testcases
33
import android.util.Log
44
import android.view.View
55
import me.yifeiyuan.flap.FlapAdapter
6-
import me.yifeiyuan.flap.ext.FlapItemTouchHelper
6+
import me.yifeiyuan.flap.ext.SwipeDragHelper
77

88

99
private const val TAG = "ItemClicksTestcase"
@@ -18,9 +18,19 @@ class SwipeAndDragTestcase : BaseTestcaseFragment() {
1818
override fun onInit(view: View) {
1919
super.onInit(view)
2020

21-
FlapItemTouchHelper(adapter).apply {
22-
isLongPressDragEnable = true
21+
SwipeDragHelper(adapter).apply {
22+
isDragEnable = true
2323
isSwipeEnable = true
24+
// swipeFlags = ItemTouchHelper.START
25+
26+
doOnMove { fromPosition, toPosition ->
27+
toast("移动交换了 $fromPosition to $toPosition")
28+
}
29+
30+
doOnDismiss {
31+
toast("滑动删除了一个 item , position=$it")
32+
}
33+
2434
attachToRecyclerView(recyclerView)
2535
}
2636

flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import me.yifeiyuan.flap.service.AdapterServiceManager
3232
* @since 2020/9/22
3333
* @since 3.0.0
3434
*/
35-
open class FlapAdapter : RecyclerView.Adapter<Component<*>>(), IRegistry, IAdapterServiceManager {
35+
open class FlapAdapter : RecyclerView.Adapter<Component<*>>(), IRegistry, IAdapterServiceManager, SwipeDragHelper.Callback {
3636

3737
companion object {
3838
private const val TAG = "FlapAdapter"
@@ -549,16 +549,24 @@ open class FlapAdapter : RecyclerView.Adapter<Component<*>>(), IRegistry, IAdapt
549549
}
550550
}
551551

552-
fun swapData(position: Int, targetPosition: Int, notify: Boolean = true) {
553-
Collections.swap(data, position, targetPosition)
552+
fun swapData(fromPosition: Int, toPosition: Int, notify: Boolean = true) {
553+
Collections.swap(data, fromPosition, toPosition)
554554
if (notify) {
555-
notifyItemMoved(position,targetPosition)
555+
notifyItemMoved(fromPosition, toPosition)
556556
}
557557
}
558558

559-
/**
560-
* 当 Adapter.data 中存在一个 Model 没有对应的 AdapterDelegate.delegate()==true 时抛出
561-
*/
562-
internal class AdapterDelegateNotFoundException(errorMessage: String) : Exception(errorMessage)
559+
override fun onItemDismiss(position: Int) {
560+
removeDataAt(position)
561+
}
562+
563+
override fun onItemMoved(fromPosition: Int, toPosition: Int) {
564+
swapData(fromPosition, toPosition)
565+
}
563566
}
564567

568+
/**
569+
* 当 Adapter.data 中存在一个 Model 没有对应的 AdapterDelegate.delegate()==true 时抛出
570+
*/
571+
internal class AdapterDelegateNotFoundException(errorMessage: String) : Exception(errorMessage)
572+

flap/src/main/java/me/yifeiyuan/flap/ext/FlapItemTouchHelper.kt

Lines changed: 0 additions & 92 deletions
This file was deleted.
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package me.yifeiyuan.flap.ext
2+
3+
import android.graphics.Canvas
4+
import android.util.Log
5+
import androidx.recyclerview.widget.*
6+
import me.yifeiyuan.flap.FlapDebug
7+
8+
/**
9+
*
10+
* 封装处理 滑动删除 和 长按拖放排序 功能
11+
*
12+
* Created by 程序亦非猿 on 2022/8/17.
13+
*
14+
* @since 3.0.6
15+
*/
16+
class SwipeDragHelper(private val callback: Callback) : ItemTouchHelper.Callback() {
17+
18+
/**
19+
* 拖动是否可用
20+
*/
21+
var isDragEnable = true
22+
23+
/**
24+
* 滑动删除是否可用
25+
*/
26+
var isSwipeEnable = true
27+
28+
var dragFlags = -1
29+
var swipeFlags = -1
30+
31+
var swipeThreshold = 0.5f
32+
var dragThreshold = 0.5f
33+
34+
private var onMove: ((fromPosition: Int, toPosition: Int) -> Unit)? = null
35+
private var onDismiss: ((position: Int) -> Unit)? = null
36+
37+
private val itemTouchHelper: ItemTouchHelper = ItemTouchHelper(this)
38+
39+
override fun isLongPressDragEnabled(): Boolean {
40+
return isDragEnable
41+
}
42+
43+
override fun isItemViewSwipeEnabled(): Boolean {
44+
return isSwipeEnable
45+
}
46+
47+
override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
48+
val finalDragFlags = if (dragFlags != -1) dragFlags else genDefaultDragFlags(recyclerView, viewHolder)
49+
val finalSwipeFlags = if (swipeFlags != -1) swipeFlags else genDefaultSwipeFlags(recyclerView, viewHolder)
50+
return makeMovementFlags(finalDragFlags, finalSwipeFlags)
51+
}
52+
53+
private fun genDefaultDragFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
54+
return when (recyclerView.layoutManager) {
55+
is StaggeredGridLayoutManager -> {
56+
ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
57+
}
58+
is GridLayoutManager -> {
59+
ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
60+
}
61+
is LinearLayoutManager -> {
62+
ItemTouchHelper.UP or ItemTouchHelper.DOWN
63+
}
64+
else -> {
65+
ItemTouchHelper.UP or ItemTouchHelper.DOWN
66+
}
67+
}
68+
}
69+
70+
private fun genDefaultSwipeFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
71+
return when (recyclerView.layoutManager) {
72+
is StaggeredGridLayoutManager -> {
73+
ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
74+
}
75+
is GridLayoutManager -> {
76+
ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
77+
}
78+
is LinearLayoutManager -> {
79+
ItemTouchHelper.START or ItemTouchHelper.END
80+
}
81+
else -> {
82+
ItemTouchHelper.START or ItemTouchHelper.END
83+
}
84+
}
85+
}
86+
87+
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
88+
if (viewHolder.itemViewType == target.itemViewType) {
89+
onMove?.invoke(viewHolder.adapterPosition, target.adapterPosition)
90+
return true
91+
}
92+
return false
93+
}
94+
95+
fun doOnMove(block: (fromPosition: Int, toPosition: Int) -> Unit) {
96+
onMove = block
97+
}
98+
99+
//Item 被滑动删除了调用
100+
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
101+
onDismiss?.invoke(viewHolder.adapterPosition)
102+
callback.onItemDismiss(viewHolder.adapterPosition)
103+
}
104+
105+
fun doOnDismiss(block: (position: Int) -> Unit) {
106+
onDismiss = block
107+
}
108+
109+
fun attachToRecyclerView(recyclerView: RecyclerView) {
110+
itemTouchHelper.attachToRecyclerView(recyclerView)
111+
}
112+
113+
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
114+
super.onSelectedChanged(viewHolder, actionState)
115+
}
116+
117+
override fun getSwipeThreshold(viewHolder: RecyclerView.ViewHolder): Float {
118+
return swipeThreshold
119+
}
120+
121+
override fun getMoveThreshold(viewHolder: RecyclerView.ViewHolder): Float {
122+
return dragThreshold
123+
}
124+
125+
/**
126+
* onMove return true 后会调用
127+
*/
128+
override fun onMoved(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, fromPos: Int, target: RecyclerView.ViewHolder, toPos: Int, x: Int, y: Int) {
129+
super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
130+
callback.onItemMoved(fromPos, toPos)
131+
}
132+
133+
/**
134+
* 当用户交互完成后调用,此时动画也结束了,例如滑动删除后、拖放完毕
135+
* 在 onViewDetachedFromWindow 之后
136+
*/
137+
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
138+
super.clearView(recyclerView, viewHolder)
139+
}
140+
141+
override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
142+
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
143+
}
144+
145+
override fun onChildDrawOver(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder?, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
146+
super.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
147+
}
148+
149+
interface Callback {
150+
fun onItemDismiss(position: Int)
151+
fun onItemMoved(fromPosition: Int, toPosition: Int)
152+
}
153+
}

0 commit comments

Comments
 (0)