Skip to content

Commit 80d9152

Browse files
committed
implemented properties to control view and animations. implemented listeners.
1 parent a28cc1c commit 80d9152

File tree

12 files changed

+274
-21
lines changed

12 files changed

+274
-21
lines changed

app/src/main/java/github/com/st235/swipetoactionlayout/MainActivity.kt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ package github.com.st235.swipetoactionlayout
33
import android.graphics.Color
44
import android.graphics.drawable.ColorDrawable
55
import android.os.Bundle
6+
import android.view.View
7+
import android.widget.Toast
68
import androidx.appcompat.app.AppCompatActivity
9+
import github.com.st235.lib_swipetoactionlayout.MenuListener
710
import github.com.st235.lib_swipetoactionlayout.SwipeAction
811
import github.com.st235.lib_swipetoactionlayout.SwipeToActionLayout
912

@@ -16,14 +19,38 @@ class MainActivity : AppCompatActivity() {
1619
setContentView(R.layout.activity_main)
1720

1821
deprecatedSwipeToActionLayout = findViewById(R.id.swipeToActionLayout)
22+
deprecatedSwipeToActionLayout.gravity = SwipeToActionLayout.MenuGravity.END
1923
deprecatedSwipeToActionLayout.isFullActionSupported = true
20-
// deprecatedSwipeToActionLayout.thresholdToOpenView = 0.0F
24+
deprecatedSwipeToActionLayout.shouldVibrateOnQuickAction = true
25+
deprecatedSwipeToActionLayout.menuListener = MenuListener()
2126

2227
deprecatedSwipeToActionLayout.actions =
2328
listOf(
2429
SwipeAction(0, ColorDrawable(0xFFFBDAEE.toInt()), R.drawable.baseline_call_24, getString(R.string.action_call), Color.BLACK, Color.BLACK),
2530
SwipeAction(1, ColorDrawable(0xFFFFF7A4.toInt()), R.drawable.baseline_email_24, getString(R.string.action_email), Color.BLACK, Color.BLACK),
2631
SwipeAction(3, ColorDrawable(0xFFC0E7F6.toInt()), R.drawable.baseline_duo_24, getString(R.string.action_duo), Color.BLACK, Color.BLACK)
2732
)
33+
34+
35+
}
36+
37+
private inner class MenuListener: github.com.st235.lib_swipetoactionlayout.MenuListener {
38+
39+
override fun onClosed(view: View) {
40+
}
41+
42+
override fun onOpened(view: View) {
43+
}
44+
45+
override fun onFullyOpened(view: View) {
46+
deprecatedSwipeToActionLayout.postDelayed({
47+
deprecatedSwipeToActionLayout.close()
48+
}, 1_000)
49+
}
50+
51+
override fun onActionClicked(view: View, action: SwipeAction) {
52+
Toast.makeText(this@MainActivity, "On clicked on: ${action.text}", Toast.LENGTH_SHORT).show()
53+
deprecatedSwipeToActionLayout.close()
54+
}
2855
}
2956
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2-
package="github.com.st235.lib_swipetoactionlayout"/>
2+
package="github.com.st235.lib_swipetoactionlayout">
3+
<uses-permission android:name="android.permission.VIBRATE" />
4+
</manifest>

lib-swipetoactionlayout/src/main/java/github/com/st235/lib_swipetoactionlayout/OnSwipeListener.kt renamed to lib-swipetoactionlayout/src/main/java/github/com/st235/lib_swipetoactionlayout/MenuListener.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package github.com.st235.lib_swipetoactionlayout
22

33
import android.view.View
44

5-
interface OnSwipeListener {
5+
interface MenuListener {
66
fun onClosed(view: View)
77
fun onOpened(view: View)
8-
fun onSlide(view: View, slideOffset: Float)
8+
fun onFullyOpened(view: View)
9+
10+
fun onActionClicked(view: View, action: SwipeAction)
911
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package github.com.st235.lib_swipetoactionlayout
2+
3+
internal enum class QuickActionsStates {
4+
OPENED, CLOSED, FULL_OPENED
5+
}

lib-swipetoactionlayout/src/main/java/github/com/st235/lib_swipetoactionlayout/SwipeToActionLayout.kt

Lines changed: 93 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import androidx.customview.widget.ViewDragHelper
88
import github.com.st235.lib_swipetoactionlayout.behaviour.BehaviourDelegate
99
import github.com.st235.lib_swipetoactionlayout.behaviour.BehaviourDelegatesFactory
1010
import github.com.st235.lib_swipetoactionlayout.behaviour.NoOpBehaviourDelegate
11+
import github.com.st235.lib_swipetoactionlayout.events.QuickActionsMenuStateProcessor
1112
import github.com.st235.lib_swipetoactionlayout.utils.isLtr
1213
import github.com.st235.lib_swipetoactionlayout.utils.max
1314
import github.com.st235.lib_swipetoactionlayout.utils.min
@@ -65,25 +66,78 @@ class SwipeToActionLayout @JvmOverloads constructor(
6566
}
6667

6768
var gravity: MenuGravity = MenuGravity.RIGHT
68-
set(value) {
69-
field = value
70-
reloadActions()
71-
}
69+
set(value) {
70+
field = value
71+
reloadActions()
72+
}
7273

7374
var isFullActionSupported: Boolean = false
74-
set(value) {
75-
field = value
76-
reloadActions()
77-
}
75+
set(value) {
76+
field = value
77+
reloadActions()
78+
}
79+
80+
var shouldVibrateOnQuickAction: Boolean = false
7881

7982
private val actionFactory = ActionFactory(context)
8083
private val behaviourDelegateFactory = BehaviourDelegatesFactory(context)
8184

85+
private var inProgressStateProcessor = QuickActionsMenuStateProcessor()
86+
8287
private var actionSize = 0
8388

8489
private var delegate: BehaviourDelegate = NoOpBehaviourDelegate()
8590
private val viewDragHelper = ViewDragHelper.create(this, ViewDragHelperCallback())
8691

92+
var menuListener: MenuListener? = null
93+
94+
init {
95+
inProgressStateProcessor.onReleaseStateChanged = { state ->
96+
when (state) {
97+
QuickActionsStates.FULL_OPENED -> {
98+
menuListener?.onFullyOpened(this)
99+
}
100+
QuickActionsStates.OPENED -> {
101+
menuListener?.onOpened(this)
102+
}
103+
QuickActionsStates.CLOSED -> {
104+
menuListener?.onClosed(this)
105+
}
106+
}
107+
108+
}
109+
110+
inProgressStateProcessor.onProgressiveStateChanged = { state ->
111+
when (state) {
112+
QuickActionsStates.FULL_OPENED -> {
113+
if (shouldVibrateOnQuickAction) {
114+
performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK)
115+
}
116+
}
117+
else -> {
118+
}
119+
}
120+
}
121+
}
122+
123+
fun close() {
124+
transitionToState(QuickActionsStates.CLOSED)
125+
}
126+
127+
fun open() {
128+
transitionToState(QuickActionsStates.OPENED)
129+
}
130+
131+
fun fullyOpen() {
132+
transitionToState(QuickActionsStates.FULL_OPENED)
133+
}
134+
135+
private fun transitionToState(state: QuickActionsStates) {
136+
val position = delegate.gePositionForState(this, actionSize, state)
137+
viewDragHelper.smoothSlideViewTo(findContentView(), position, 0)
138+
invalidate()
139+
}
140+
87141
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
88142
var contentWidth = 0
89143
var contentHeight = 0
@@ -156,7 +210,7 @@ class SwipeToActionLayout @JvmOverloads constructor(
156210
val mode = MeasureSpec.getMode(measureSpec)
157211
val availableSize = MeasureSpec.getSize(measureSpec)
158212

159-
return when(mode) {
213+
return when (mode) {
160214
MeasureSpec.EXACTLY -> availableSize
161215
MeasureSpec.AT_MOST -> min(availableSize, size)
162216
MeasureSpec.UNSPECIFIED -> size
@@ -207,6 +261,18 @@ class SwipeToActionLayout @JvmOverloads constructor(
207261
}
208262
}
209263

264+
private fun findContentView(): View {
265+
for (i in 0 until childCount) {
266+
val child = getChildAt(i)
267+
268+
if (!ActionFactory.isAction(child)) {
269+
return child
270+
}
271+
}
272+
273+
throw IllegalStateException()
274+
}
275+
210276
private fun reloadActions() {
211277
val items = actions
212278

@@ -216,7 +282,15 @@ class SwipeToActionLayout @JvmOverloads constructor(
216282

217283
for ((index, item) in items.withIndex()) {
218284
val isLastItem = (index == items.lastIndex)
219-
val associatedView = actionFactory.createAction(item, isLastItem, gravity.getViewGravity())
285+
val associatedView =
286+
actionFactory.createAction(item, isLastItem, gravity.getViewGravity())
287+
288+
associatedView.isClickable = true
289+
associatedView.isFocusable = true
290+
associatedView.setOnClickListener {
291+
menuListener?.onActionClicked(it, action = item)
292+
}
293+
220294
addView(associatedView)
221295
}
222296

@@ -239,7 +313,7 @@ class SwipeToActionLayout @JvmOverloads constructor(
239313
}
240314
}
241315

242-
private inner class ViewDragHelperCallback: ViewDragHelper.Callback() {
316+
private inner class ViewDragHelperCallback : ViewDragHelper.Callback() {
243317

244318
override fun tryCaptureView(child: View, pointerId: Int): Boolean {
245319
return !ActionFactory.isAction(child)
@@ -265,11 +339,19 @@ class SwipeToActionLayout @JvmOverloads constructor(
265339
actionOrder++
266340
}
267341
}
342+
343+
inProgressStateProcessor.setState(
344+
delegate.getStateForPosition(
345+
changedView,
346+
actionSize
347+
)
348+
)
268349
}
269350

270351
override fun onViewReleased(releasedChild: View, xvel: Float, yvel: Float) {
271352
val finalLeftPosition = delegate.getFinalLeftPosition(releasedChild, xvel, actionSize)
272353
viewDragHelper.settleCapturedViewAt(finalLeftPosition, 0)
354+
inProgressStateProcessor.release()
273355
invalidate()
274356
}
275357
}

lib-swipetoactionlayout/src/main/java/github/com/st235/lib_swipetoactionlayout/behaviour/BehaviourDelegate.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package github.com.st235.lib_swipetoactionlayout.behaviour
22

33
import android.graphics.Point
44
import android.view.View
5+
import github.com.st235.lib_swipetoactionlayout.QuickActionsStates
56

67
internal interface BehaviourDelegate {
78

@@ -15,4 +16,8 @@ internal interface BehaviourDelegate {
1516

1617
fun getFinalLeftPosition(view: View, velocity: Float, actionSize: Int): Int
1718

19+
fun getStateForPosition(view: View, actionSize: Int): QuickActionsStates
20+
21+
fun gePositionForState(view: View, actionSize: Int, states: QuickActionsStates): Int
22+
1823
}

lib-swipetoactionlayout/src/main/java/github/com/st235/lib_swipetoactionlayout/behaviour/FullLeftDirectedBehaviorDelegate.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.content.Context
55
import android.view.View
66
import androidx.core.animation.addListener
77
import github.com.st235.lib_swipetoactionlayout.ActionFactory
8+
import github.com.st235.lib_swipetoactionlayout.QuickActionsStates
89
import github.com.st235.lib_swipetoactionlayout.utils.clamp
910
import github.com.st235.lib_swipetoactionlayout.utils.max
1011
import github.com.st235.lib_swipetoactionlayout.utils.min
@@ -147,5 +148,25 @@ internal class FullLeftDirectedBehaviorDelegate(
147148
return position > translateDistance
148149
}
149150

151+
override fun getStateForPosition(
152+
view: View,
153+
actionSize: Int
154+
): QuickActionsStates {
155+
return if (isFullyOpened(view, actionSize)) {
156+
QuickActionsStates.FULL_OPENED
157+
} else if (isOpened(view.left, actionSize)) {
158+
QuickActionsStates.OPENED
159+
} else {
160+
QuickActionsStates.CLOSED
161+
}
162+
}
163+
164+
override fun gePositionForState(view: View, actionSize: Int, states: QuickActionsStates): Int {
165+
return when(states) {
166+
QuickActionsStates.FULL_OPENED -> view.measuredWidth
167+
QuickActionsStates.OPENED -> actionSize * actionCount
168+
QuickActionsStates.CLOSED -> 0
169+
}
170+
}
150171

151172
}

lib-swipetoactionlayout/src/main/java/github/com/st235/lib_swipetoactionlayout/behaviour/FullRightDirectedBehaviorDelegate.kt

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.content.Context
55
import android.view.View
66
import androidx.core.animation.addListener
77
import github.com.st235.lib_swipetoactionlayout.ActionFactory
8+
import github.com.st235.lib_swipetoactionlayout.QuickActionsStates
89
import github.com.st235.lib_swipetoactionlayout.utils.clamp
910

1011
internal class FullRightDirectedBehaviorDelegate(
@@ -110,12 +111,16 @@ internal class FullRightDirectedBehaviorDelegate(
110111
override fun getFinalLeftPosition(view: View, velocity: Float, actionSize: Int): Int {
111112
val translateDistance = actionSize * actionCount
112113

113-
return if (isFullyOpened(view, actionSize)) {
114-
-view.measuredWidth
115-
} else if (isOpened(view.left, actionSize)) {
116-
-translateDistance
117-
} else {
118-
0
114+
return when {
115+
isFullyOpened(view, actionSize) -> {
116+
-view.measuredWidth
117+
}
118+
isOpened(view.left, actionSize) -> {
119+
-translateDistance
120+
}
121+
else -> {
122+
0
123+
}
119124
}
120125
}
121126

@@ -127,5 +132,29 @@ internal class FullRightDirectedBehaviorDelegate(
127132
return position < -translateDistance
128133
}
129134

135+
override fun getStateForPosition(
136+
view: View,
137+
actionSize: Int
138+
): QuickActionsStates {
139+
return when {
140+
isFullyOpened(view, actionSize) -> {
141+
QuickActionsStates.FULL_OPENED
142+
}
143+
isOpened(view.left, actionSize) -> {
144+
QuickActionsStates.OPENED
145+
}
146+
else -> {
147+
QuickActionsStates.CLOSED
148+
}
149+
}
150+
}
151+
152+
override fun gePositionForState(view: View, actionSize: Int, states: QuickActionsStates): Int {
153+
return when(states) {
154+
QuickActionsStates.FULL_OPENED -> -view.measuredWidth
155+
QuickActionsStates.OPENED -> -(actionSize * actionCount)
156+
QuickActionsStates.CLOSED -> 0
157+
}
158+
}
130159

131160
}

lib-swipetoactionlayout/src/main/java/github/com/st235/lib_swipetoactionlayout/behaviour/LeftDirectedBehaviourDelegate.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.content.Context
44
import android.graphics.Point
55
import android.util.Log
66
import android.view.View
7+
import github.com.st235.lib_swipetoactionlayout.QuickActionsStates
78
import github.com.st235.lib_swipetoactionlayout.utils.clamp
89

910
internal open class LeftDirectedBehaviourDelegate(
@@ -42,4 +43,22 @@ internal open class LeftDirectedBehaviourDelegate(
4243
}
4344
}
4445

46+
override fun getStateForPosition(
47+
view: View,
48+
actionSize: Int
49+
): QuickActionsStates {
50+
return if (isOpened(view.left, actionSize)) {
51+
QuickActionsStates.OPENED
52+
} else {
53+
QuickActionsStates.CLOSED
54+
}
55+
}
56+
57+
override fun gePositionForState(view: View, actionSize: Int, states: QuickActionsStates): Int {
58+
return when(states) {
59+
QuickActionsStates.FULL_OPENED -> throw IllegalArgumentException("Unsupported state")
60+
QuickActionsStates.OPENED -> actionSize * actionCount
61+
QuickActionsStates.CLOSED -> 0
62+
}
63+
}
4564
}

0 commit comments

Comments
 (0)