1
+ package me.yifeiyuan.flap.ext
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.Color
5
+ import android.graphics.drawable.ColorDrawable
6
+ import android.graphics.drawable.Drawable
7
+ import androidx.recyclerview.widget.*
8
+
9
+ /* *
10
+ *
11
+ * 封装处理 滑动删除 和 长按拖放排序 功能
12
+ *
13
+ * Created by 程序亦非猿 on 2022/8/17.
14
+ *
15
+ * @since 3.0.6
16
+ */
17
+ class SwipeDragHelper (private val callback : Callback ) : ItemTouchHelper.Callback() {
18
+
19
+ /* *
20
+ * 拖动是否可用
21
+ */
22
+ private var isDragEnable = true
23
+
24
+ /* *
25
+ * 滑动删除是否可用
26
+ */
27
+ private var isSwipeEnable = true
28
+
29
+ private var dragFlags = - 1
30
+ private var swipeFlags = - 1
31
+
32
+ private var swipeThreshold = 0.5f
33
+ private var dragThreshold = 0.5f
34
+
35
+ private var onMove: ((fromPosition: Int , toPosition: Int ) -> Unit )? = null
36
+ private var onDismiss: ((position: Int ) -> Unit )? = null
37
+
38
+ private var swipeBackground: Drawable ? = null
39
+
40
+ private val itemTouchHelper: ItemTouchHelper = ItemTouchHelper (this )
41
+
42
+ override fun isLongPressDragEnabled (): Boolean {
43
+ return isDragEnable
44
+ }
45
+
46
+ override fun isItemViewSwipeEnabled (): Boolean {
47
+ return isSwipeEnable
48
+ }
49
+
50
+ override fun getMovementFlags (recyclerView : RecyclerView , viewHolder : RecyclerView .ViewHolder ): Int {
51
+ val finalDragFlags = if (dragFlags != - 1 ) dragFlags else genDefaultDragFlags(recyclerView, viewHolder)
52
+ val finalSwipeFlags = if (swipeFlags != - 1 ) swipeFlags else genDefaultSwipeFlags(recyclerView, viewHolder)
53
+ return makeMovementFlags(finalDragFlags, finalSwipeFlags)
54
+ }
55
+
56
+ private fun genDefaultDragFlags (recyclerView : RecyclerView , viewHolder : RecyclerView .ViewHolder ): Int {
57
+ return when (recyclerView.layoutManager) {
58
+ is StaggeredGridLayoutManager -> {
59
+ ItemTouchHelper .UP or ItemTouchHelper .DOWN or ItemTouchHelper .LEFT or ItemTouchHelper .RIGHT
60
+ }
61
+ is GridLayoutManager -> {
62
+ ItemTouchHelper .UP or ItemTouchHelper .DOWN or ItemTouchHelper .LEFT or ItemTouchHelper .RIGHT
63
+ }
64
+ is LinearLayoutManager -> {
65
+ ItemTouchHelper .UP or ItemTouchHelper .DOWN
66
+ }
67
+ else -> {
68
+ ItemTouchHelper .UP or ItemTouchHelper .DOWN
69
+ }
70
+ }
71
+ }
72
+
73
+ private fun genDefaultSwipeFlags (recyclerView : RecyclerView , viewHolder : RecyclerView .ViewHolder ): Int {
74
+ return when (recyclerView.layoutManager) {
75
+ is StaggeredGridLayoutManager -> {
76
+ ItemTouchHelper .UP or ItemTouchHelper .DOWN or ItemTouchHelper .LEFT or ItemTouchHelper .RIGHT
77
+ }
78
+ is GridLayoutManager -> {
79
+ ItemTouchHelper .UP or ItemTouchHelper .DOWN or ItemTouchHelper .LEFT or ItemTouchHelper .RIGHT
80
+ }
81
+ is LinearLayoutManager -> {
82
+ ItemTouchHelper .START or ItemTouchHelper .END
83
+ }
84
+ else -> {
85
+ ItemTouchHelper .START or ItemTouchHelper .END
86
+ }
87
+ }
88
+ }
89
+
90
+ override fun onMove (recyclerView : RecyclerView , viewHolder : RecyclerView .ViewHolder , target : RecyclerView .ViewHolder ): Boolean {
91
+ if (viewHolder.itemViewType == target.itemViewType) {
92
+ onMove?.invoke(viewHolder.adapterPosition, target.adapterPosition)
93
+ return true
94
+ }
95
+ return false
96
+ }
97
+
98
+ fun onItemMove (block : (fromPosition: Int , toPosition: Int ) -> Unit ): SwipeDragHelper {
99
+ onMove = block
100
+ return this
101
+ }
102
+
103
+ // Item 被滑动删除了调用
104
+ override fun onSwiped (viewHolder : RecyclerView .ViewHolder , direction : Int ) {
105
+ onDismiss?.invoke(viewHolder.adapterPosition)
106
+ callback.onItemDismiss(viewHolder.adapterPosition)
107
+ }
108
+
109
+ fun onItemDismiss (block : (position: Int ) -> Unit ): SwipeDragHelper {
110
+ onDismiss = block
111
+ return this
112
+ }
113
+
114
+ fun attachToRecyclerView (recyclerView : RecyclerView ): SwipeDragHelper {
115
+ itemTouchHelper.attachToRecyclerView(recyclerView)
116
+ return this
117
+ }
118
+
119
+ override fun onSelectedChanged (viewHolder : RecyclerView .ViewHolder ? , actionState : Int ) {
120
+ super .onSelectedChanged(viewHolder, actionState)
121
+ }
122
+
123
+ override fun getSwipeThreshold (viewHolder : RecyclerView .ViewHolder ): Float {
124
+ return swipeThreshold
125
+ }
126
+
127
+ override fun getMoveThreshold (viewHolder : RecyclerView .ViewHolder ): Float {
128
+ return dragThreshold
129
+ }
130
+
131
+ /* *
132
+ * onMove return true 后会调用
133
+ */
134
+ override fun onMoved (recyclerView : RecyclerView , viewHolder : RecyclerView .ViewHolder , fromPos : Int , target : RecyclerView .ViewHolder , toPos : Int , x : Int , y : Int ) {
135
+ super .onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
136
+ callback.onItemMoved(fromPos, toPos)
137
+ }
138
+
139
+ /* *
140
+ * 当用户交互完成后调用,此时动画也结束了,例如滑动删除后、拖放完毕
141
+ * 在 onViewDetachedFromWindow 之后
142
+ */
143
+ override fun clearView (recyclerView : RecyclerView , viewHolder : RecyclerView .ViewHolder ) {
144
+ super .clearView(recyclerView, viewHolder)
145
+ }
146
+
147
+ override fun onChildDraw (c : Canvas , recyclerView : RecyclerView , viewHolder : RecyclerView .ViewHolder , dX : Float , dY : Float , actionState : Int , isCurrentlyActive : Boolean ) {
148
+ super .onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
149
+ if (actionState == ItemTouchHelper .ACTION_STATE_SWIPE ) {
150
+ // 滑动的时候可以绘制背景
151
+ swipeBackground?.let {
152
+ val itemView = viewHolder.itemView
153
+ if (dX > 0 ) {
154
+ it.setBounds(itemView.left, itemView.top, itemView.left + dX.toInt(), itemView.bottom)
155
+ it.draw(c)
156
+ } else {
157
+ it.setBounds(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)
158
+ it.draw(c)
159
+ }
160
+ }
161
+ } else if (actionState == ItemTouchHelper .ACTION_STATE_DRAG ) {
162
+ // 拖动
163
+ }
164
+ }
165
+
166
+ override fun onChildDrawOver (c : Canvas , recyclerView : RecyclerView , viewHolder : RecyclerView .ViewHolder ? , dX : Float , dY : Float , actionState : Int , isCurrentlyActive : Boolean ) {
167
+ super .onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
168
+ }
169
+
170
+ /* *
171
+ * 拖动是否可用
172
+ */
173
+ fun withDragEnable (enable : Boolean ): SwipeDragHelper {
174
+ isDragEnable = enable
175
+ return this
176
+ }
177
+
178
+ /* *
179
+ * 滑动删除是否可用
180
+ */
181
+ fun withSwipeEnable (enable : Boolean ): SwipeDragHelper {
182
+ isSwipeEnable = enable
183
+ return this
184
+ }
185
+
186
+ fun withDragFlags (dragFlags : Int ): SwipeDragHelper {
187
+ this .dragFlags = dragFlags
188
+ return this
189
+ }
190
+
191
+ fun withSwipeFlags (swipeFlags : Int ): SwipeDragHelper {
192
+ this .swipeFlags = swipeFlags
193
+ return this
194
+ }
195
+
196
+ fun withSwipeThreshold (swipeThreshold : Float ): SwipeDragHelper {
197
+ this .swipeThreshold = swipeThreshold
198
+ return this
199
+ }
200
+
201
+ fun withDragThreshold (dragThreshold : Float ): SwipeDragHelper {
202
+ this .dragThreshold = dragThreshold
203
+ return this
204
+ }
205
+
206
+ fun withSwipeBackground (swipeBackground : Drawable ): SwipeDragHelper {
207
+ this .swipeBackground = swipeBackground
208
+ return this
209
+ }
210
+
211
+ interface Callback {
212
+ fun onItemDismiss (position : Int )
213
+ fun onItemMoved (fromPosition : Int , toPosition : Int )
214
+ }
215
+ }
0 commit comments