@@ -2,21 +2,23 @@ package github.com.st235.lib_swipetoactionlayout
22
33import android.annotation.SuppressLint
44import android.graphics.PorterDuff
5- import android.graphics.Rect
65import android.text.TextUtils
76import android.view.View
87import android.widget.FrameLayout
98import android.widget.LinearLayout
109import android.widget.TextView
1110import androidx.appcompat.widget.AppCompatImageView
11+ import github.com.st235.lib_swipetoactionlayout.ActionParamsResolver.Companion.EMPTY_INFO
1212import 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