Skip to content

Commit ea65a66

Browse files
author
Alexander Dadukin
committed
implemented action layout without callbacks
1 parent 889fbbf commit ea65a66

File tree

5 files changed

+228
-105
lines changed

5 files changed

+228
-105
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ internal class ActionParamsResolver {
1717
val shouldTruncateText: Boolean = false
1818
)
1919

20+
companion object {
21+
val EMPTY_INFO = ActionInfo(
22+
textSize = 14F,
23+
actionHeight = 0,
24+
actionWidth = 0,
25+
maxLines = 1
26+
)
27+
}
28+
2029
private val textPaint = TextPaint(TextPaint.ANTI_ALIAS_FLAG)
2130

2231
fun obtainActionInfoFor(
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package github.com.st235.lib_swipetoactionlayout
2+
3+
import android.view.View
4+
5+
internal interface ActionViewObserver {
6+
fun onInit(width: Int, height: Int, actions: List<SwipeAction>) { }
7+
fun onMeasure(width: Int, height: Int, actions: List<SwipeAction>, views: List<View>, gravity: SwipeActionActionViewFactory.Gravity)
8+
fun onLayout(width: Int, height: Int, actions: List<SwipeAction>, views: List<View>, gravity: SwipeActionActionViewFactory.Gravity)
9+
}

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

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,29 @@ import android.widget.FrameLayout
1313

1414
internal class HudViewController(
1515
context: Context,
16-
private val swipeActionViewFactory: SwipeActionViewFactory
17-
) {
16+
private val swipeActionViewFactory: SwipeActionActionViewFactory
17+
): ActionViewObserver {
1818

1919
private val hudView: ViewGroup = FrameLayout(context)
2020

2121
private lateinit var leftActionView: View
2222
private lateinit var rightActionView: View
2323

24-
fun attachToParent(parent: ViewGroup, firstAction: SwipeAction) {
24+
fun attachToParent(parent: ViewGroup, action: SwipeAction) {
2525
val lp = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
2626
hudView.setBackgroundColor(Color.TRANSPARENT)
2727
parent.addView(hudView, lp)
2828

29-
30-
val desiredSize = Math.min(parent.width, parent.height)
31-
3229
leftActionView = swipeActionViewFactory.create(
33-
action = firstAction,
34-
actionInfo = swipeActionViewFactory.lastKnownActionInfo,
35-
gravity = SwipeActionViewFactory.Gravity.LEFT
30+
action = action,
31+
gravity = SwipeActionActionViewFactory.Gravity.LEFT
3632
)
3733

3834
leftActionView.visibility = View.INVISIBLE
3935

4036
rightActionView = swipeActionViewFactory.create(
41-
action = firstAction,
42-
actionInfo = swipeActionViewFactory.lastKnownActionInfo,
43-
gravity = SwipeActionViewFactory.Gravity.RIGHT
37+
action = action,
38+
gravity = SwipeActionActionViewFactory.Gravity.RIGHT
4439
)
4540

4641
rightActionView.visibility = View.INVISIBLE
@@ -53,6 +48,29 @@ internal class HudViewController(
5348
parent.removeView(hudView)
5449
}
5550

51+
override fun onMeasure(
52+
width: Int,
53+
height: Int,
54+
actions: List<SwipeAction>,
55+
views: List<View>,
56+
gravity: SwipeActionActionViewFactory.Gravity
57+
) {
58+
hudView.measure(
59+
View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
60+
View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
61+
)
62+
}
63+
64+
override fun onLayout(
65+
width: Int,
66+
height: Int,
67+
actions: List<SwipeAction>,
68+
views: List<View>,
69+
gravity: SwipeActionActionViewFactory.Gravity
70+
) {
71+
hudView.layout(0, 0, width, height)
72+
}
73+
5674
fun hideIfNeeded() {
5775
if (hudView.visibility != View.INVISIBLE) {
5876
hudView.visibility = View.INVISIBLE

lib-swipetoactionlayout/src/main/java/github/com/st235/lib_swipetoactionlayout/SwipeActionViewFactory.kt renamed to lib-swipetoactionlayout/src/main/java/github/com/st235/lib_swipetoactionlayout/SwipeActionActionViewFactory.kt

Lines changed: 83 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,23 @@ package github.com.st235.lib_swipetoactionlayout
22

33
import android.annotation.SuppressLint
44
import android.graphics.PorterDuff
5-
import android.graphics.Rect
65
import android.text.TextUtils
76
import android.view.View
87
import android.widget.FrameLayout
98
import android.widget.LinearLayout
109
import android.widget.TextView
1110
import androidx.appcompat.widget.AppCompatImageView
11+
import github.com.st235.lib_swipetoactionlayout.ActionParamsResolver.Companion.EMPTY_INFO
1212
import github.com.st235.lib_swipetoactionlayout.utils.toPx
1313

14-
internal class SwipeActionViewFactory(
14+
internal class SwipeActionActionViewFactory(
1515
private val swipeToActionLayout: SwipeToActionLayout,
1616
private val onActionClickListener: OnActionClickListener
17-
) {
17+
) : ActionViewObserver {
1818

19-
val HORIZONTAL_MARGIN_IN_DP = 8F
19+
companion object {
20+
const val HORIZONTAL_MARGIN_IN_DP = 8F
21+
}
2022

2123
@SuppressLint("RtlHardcoded")
2224
enum class Gravity(internal var androidGravity: Int) {
@@ -25,71 +27,107 @@ internal class SwipeActionViewFactory(
2527
}
2628

2729
private val context = swipeToActionLayout.context
28-
private val parentBounds = Rect()
2930
private val actionParamsResolver = ActionParamsResolver()
30-
internal lateinit var lastKnownActionInfo: ActionParamsResolver.ActionInfo
31-
32-
fun onOwnerBoundsChanged(newWidth: Int, newHeight: Int) {
33-
parentBounds.set(0, 0, newWidth, newHeight)
34-
}
31+
internal var lastKnownActionInfo = EMPTY_INFO
3532

3633
fun createLayout(actions: List<SwipeAction>, gravity: Gravity): List<View> {
3734
val views = mutableListOf<View>()
38-
val desiredSize = Math.min(parentBounds.width(), parentBounds.height())
39-
lastKnownActionInfo = actionParamsResolver.obtainActionInfoFor(
40-
(parentBounds.width() * 0.9F).toInt(),
41-
Math.min(desiredSize, parentBounds.width() / actions.size), desiredSize, HORIZONTAL_MARGIN_IN_DP, actions
42-
)
43-
44-
var margin = (actions.size - 1) * desiredSize
4535

4636
if (gravity == Gravity.LEFT) {
4737
for (i in (actions.size - 1) downTo 0) {
48-
val action = actions[i]
49-
50-
val actionView = create(action, lastKnownActionInfo, margin, 0, gravity)
38+
val actionView = create(actions[i], gravity)
5139
swipeToActionLayout.addView(actionView, actionView.layoutParams)
5240

5341
views.add(0, actionView)
54-
55-
margin -= desiredSize
5642
}
5743
}
5844

59-
margin = (actions.size - 1) * desiredSize
60-
6145
if (gravity == Gravity.RIGHT) {
6246
for (i in 0 until actions.size) {
63-
val action = actions[i]
64-
65-
val actionView = create(action, lastKnownActionInfo, 0, margin, gravity)
47+
val actionView = create(actions[i], gravity)
6648
swipeToActionLayout.addView(actionView, actionView.layoutParams)
6749

6850
views.add(actionView)
69-
actionView.isClickable = true
70-
actionView.isFocusable = true
71-
72-
margin -= desiredSize
7351
}
7452
}
7553

7654
return views
7755
}
7856

57+
override fun onInit(width: Int, height: Int, actions: List<SwipeAction>) {
58+
val desiredSize = Math.min(width, height)
59+
lastKnownActionInfo = actionParamsResolver.obtainActionInfoFor(
60+
(width * 0.9F).toInt(),
61+
Math.min(desiredSize, height / actions.size), desiredSize, HORIZONTAL_MARGIN_IN_DP, actions
62+
)
63+
}
64+
65+
override fun onMeasure(
66+
width: Int,
67+
height: Int,
68+
actions: List<SwipeAction>,
69+
views: List<View>,
70+
gravity: Gravity
71+
) {
72+
if (gravity == Gravity.LEFT) {
73+
for (i in (actions.size - 1) downTo 0) {
74+
val actionView = views[i]
75+
actionView.measure(
76+
View.MeasureSpec.makeMeasureSpec(lastKnownActionInfo.actionWidth, View.MeasureSpec.EXACTLY),
77+
View.MeasureSpec.makeMeasureSpec(lastKnownActionInfo.actionHeight, View.MeasureSpec.EXACTLY)
78+
)
79+
}
80+
}
81+
82+
if (gravity == Gravity.RIGHT) {
83+
for (i in 0 until actions.size) {
84+
val actionView = views[i]
85+
actionView.measure(
86+
View.MeasureSpec.makeMeasureSpec(lastKnownActionInfo.actionWidth, View.MeasureSpec.EXACTLY),
87+
View.MeasureSpec.makeMeasureSpec(lastKnownActionInfo.actionHeight, View.MeasureSpec.EXACTLY)
88+
)
89+
}
90+
}
91+
}
92+
93+
override fun onLayout(
94+
width: Int,
95+
height: Int,
96+
actions: List<SwipeAction>,
97+
views: List<View>,
98+
gravity: Gravity
99+
) {
100+
var margin = (actions.size - 1) * lastKnownActionInfo.actionWidth
101+
if (gravity == Gravity.LEFT) {
102+
for (i in (actions.size - 1) downTo 0) {
103+
val actionView = views[i]
104+
actionView.layout(margin, 0, margin + lastKnownActionInfo.actionWidth, height)
105+
margin -= lastKnownActionInfo.actionWidth
106+
}
107+
}
108+
109+
margin = (actions.size - 1) * lastKnownActionInfo.actionWidth
110+
111+
if (gravity == Gravity.RIGHT) {
112+
for (i in 0 until actions.size) {
113+
val actionView = views[i]
114+
actionView.layout(width - margin - lastKnownActionInfo.actionWidth, 0, width - margin, height)
115+
margin -= lastKnownActionInfo.actionWidth
116+
}
117+
}
118+
}
119+
79120
internal fun create(
80121
action: SwipeAction,
81-
actionInfo: ActionParamsResolver.ActionInfo,
82-
marginLeft: Int = 0,
83-
marginRight: Int = 0,
84122
gravity: Gravity
85123
): View {
86124
val actionView = LinearLayout(context)
87125
actionView.orientation = LinearLayout.VERTICAL
88126
actionView.setVerticalGravity(android.view.Gravity.CENTER_VERTICAL)
89127
actionView.setHorizontalGravity(android.view.Gravity.CENTER_HORIZONTAL)
90-
actionView.setBackgroundColor(action.color)
91128
actionView.isFocusable = true
92129
actionView.isClickable = true
130+
actionView.setBackgroundColor(action.color)
93131
actionView.setOnClickListener { onActionClickListener(actionView, action) }
94132

95133
val iconLayoutParams = LinearLayout.LayoutParams(
@@ -107,11 +145,12 @@ internal class SwipeActionViewFactory(
107145
textLayoutParams.rightMargin = HORIZONTAL_MARGIN_IN_DP.toPx().toInt()
108146

109147
actionView.addView(createIconView(action), iconLayoutParams)
110-
actionView.addView(createTextView(action, actionInfo), textLayoutParams)
148+
actionView.addView(createTextView(action, lastKnownActionInfo), textLayoutParams)
111149

112-
val actionLayoutParams = FrameLayout.LayoutParams(actionInfo.actionWidth, actionInfo.actionHeight)
113-
actionLayoutParams.leftMargin = marginLeft
114-
actionLayoutParams.rightMargin = marginRight
150+
val actionLayoutParams =
151+
FrameLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)
152+
actionLayoutParams.leftMargin = 0
153+
actionLayoutParams.rightMargin = 0
115154
actionLayoutParams.gravity = gravity.androidGravity
116155

117156
actionView.layoutParams = actionLayoutParams
@@ -126,13 +165,16 @@ internal class SwipeActionViewFactory(
126165
return iconView
127166
}
128167

129-
private fun createTextView(action: SwipeAction, actionInfo: ActionParamsResolver.ActionInfo): View {
168+
private fun createTextView(
169+
action: SwipeAction,
170+
actionInfo: ActionParamsResolver.ActionInfo
171+
): View {
130172
val textView = TextView(context)
131173
textView.text = action.text
132174
textView.setTextColor(action.textColor)
133175
textView.textSize = actionInfo.textSize
134-
textView.gravity = android.view.Gravity.CENTER
135176
textView.maxLines = actionInfo.maxLines
177+
textView.gravity = android.view.Gravity.CENTER
136178
textView.setLineSpacing(0F, 0.9F)
137179

138180
if (actionInfo.shouldTruncateText) {

0 commit comments

Comments
 (0)