Skip to content

Commit 206d4bb

Browse files
authored
#10 Vertical ProgressBar (#11)
feat[#10]: Vertical ProgressBar implementation fix: bug on restore view state if flag to restore state is setting to false refactor: updating dependencies refactor: update version number to release refactor: update version number to release fix: update version of maven publication plugin
1 parent 744a921 commit 206d4bb

File tree

7 files changed

+161
-21
lines changed

7 files changed

+161
-21
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ dependencies {
3131
implementation("androidx.constraintlayout:constraintlayout:2.0.4")
3232

3333
testImplementation("junit:junit:4.13.2")
34-
testImplementation("org.mockito:mockito-core:3.7.7")
34+
testImplementation("org.mockito:mockito-core:3.9.0")
3535
testImplementation("androidx.test:core:1.3.0")
3636
androidTestImplementation("androidx.test.ext:junit:1.1.2")
3737
androidTestImplementation("androidx.test:runner:1.3.0")

build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ buildscript {
44
jcenter()
55
}
66
dependencies {
7-
classpath("com.android.tools.build:gradle:4.1.3")
8-
classpath(kotlin("gradle-plugin", version = "1.4.31"))
9-
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.4.20")
7+
classpath("com.android.tools.build:gradle:4.2.1")
8+
classpath(kotlin("gradle-plugin", version = "1.5.0"))
9+
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.4.32")
1010
}
1111
}
1212

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ systemProp.org.gradle.internal.publish.checksums.insecure=true
2323

2424
GROUP=io.github.geniusrus
2525
POM_ARTIFACT_ID=multiprogressbar
26-
VERSION_NAME=1.2.0
26+
VERSION_NAME=1.3.0
2727

2828
POM_NAME=MultiProgressBar
2929
POM_DESCRIPTION=Android library for multiple displays of progress like Instagram Stories

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip

multiprogressbar/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ buildscript {
77
}
88
}
99
dependencies {
10-
classpath("com.vanniktech:gradle-maven-publish-plugin:0.14.2")
10+
classpath("com.vanniktech:gradle-maven-publish-plugin:0.15.1")
1111
}
1212
}
1313

multiprogressbar/src/main/java/com/genius/multiprogressbar/MultiProgressBar.kt

Lines changed: 148 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import android.util.AttributeSet
1313
import android.view.View
1414
import android.view.animation.LinearInterpolator
1515
import androidx.annotation.FloatRange
16+
import androidx.annotation.IntDef
1617

1718
@Suppress("UNUSED")
1819
class MultiProgressBar @JvmOverloads constructor(
@@ -45,6 +46,57 @@ class MultiProgressBar @JvmOverloads constructor(
4546
private var displayedStepForListener = -1
4647
private var activeAnimator: ValueAnimator? = null
4748
private var isCompactMode: Boolean = false
49+
private var orientation: Int = Orientation.TO_RIGHT
50+
51+
private val relativePaddingStart: Int
52+
get() = when (orientation) {
53+
Orientation.TO_TOP -> paddingBottom
54+
Orientation.TO_LEFT -> paddingRight
55+
Orientation.TO_BOTTOM -> paddingTop
56+
Orientation.TO_RIGHT -> paddingLeft
57+
else -> 0
58+
}
59+
60+
private val relativePaddingEnd: Int
61+
get() = when (orientation) {
62+
Orientation.TO_TOP -> paddingTop
63+
Orientation.TO_LEFT -> paddingLeft
64+
Orientation.TO_BOTTOM -> paddingBottom
65+
Orientation.TO_RIGHT -> paddingRight
66+
else -> 0
67+
}
68+
69+
private val relativePaddingWidthStart: Int
70+
get() = when (orientation) {
71+
Orientation.TO_TOP -> paddingBottom
72+
Orientation.TO_LEFT -> paddingRight
73+
Orientation.TO_BOTTOM -> paddingTop
74+
Orientation.TO_RIGHT -> paddingLeft
75+
else -> 0
76+
}
77+
78+
private val relativePaddingWidthEnd: Int
79+
get() = when (orientation) {
80+
Orientation.TO_TOP -> paddingBottom
81+
Orientation.TO_LEFT -> paddingRight
82+
Orientation.TO_BOTTOM -> paddingTop
83+
Orientation.TO_RIGHT -> paddingLeft
84+
else -> 0
85+
}
86+
87+
private val relativeLength: Int
88+
get() = when (orientation) {
89+
Orientation.TO_TOP, Orientation.TO_BOTTOM -> measuredHeight
90+
Orientation.TO_LEFT, Orientation.TO_RIGHT -> measuredWidth
91+
else -> 0
92+
}
93+
94+
private val relativeWidth: Int
95+
get() = when (orientation) {
96+
Orientation.TO_TOP, Orientation.TO_BOTTOM -> measuredWidth
97+
Orientation.TO_LEFT, Orientation.TO_RIGHT -> measuredHeight
98+
else -> 0
99+
}
48100

49101
init {
50102
val typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.MultiProgressBar)
@@ -56,6 +108,7 @@ class MultiProgressBar @JvmOverloads constructor(
56108
progressPercents = typedArray.getInt(R.styleable.MultiProgressBar_progressPercents, 100)
57109
isNeedRestoreProgressAfterRecreate = typedArray.getBoolean(R.styleable.MultiProgressBar_isNeedRestoreProgress, false)
58110
singleDisplayedTime = typedArray.getFloat(R.styleable.MultiProgressBar_singleDisplayedTime, 1F).coerceAtLeast(0.1F)
111+
orientation = typedArray.getInt(R.styleable.MultiProgressBar_orientation, Orientation.TO_RIGHT)
59112
typedArray.recycle()
60113

61114
if (isInEditMode) {
@@ -64,8 +117,18 @@ class MultiProgressBar @JvmOverloads constructor(
64117
}
65118

66119
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
67-
val minWidth = paddingLeft + paddingRight + suggestedMinimumWidth
68-
val minHeight = suggestedMinimumHeight + paddingBottom + paddingTop + progressWidth.toInt() + 5
120+
val progressAdditionalWidth = if (orientation == Orientation.TO_BOTTOM || orientation == Orientation.TO_TOP) {
121+
progressWidth.toInt() + 5
122+
} else {
123+
0
124+
}
125+
val progressAdditionalHeight = if (orientation == Orientation.TO_RIGHT || orientation == Orientation.TO_LEFT) {
126+
progressWidth.toInt() + 5
127+
} else {
128+
0
129+
}
130+
val minWidth = paddingLeft + paddingRight + suggestedMinimumWidth + progressAdditionalWidth
131+
val minHeight = paddingBottom + paddingTop + suggestedMinimumHeight + progressAdditionalHeight
69132
setMeasuredDimension(
70133
resolveSize(minWidth, widthMeasureSpec),
71134
resolveSize(minHeight, heightMeasureSpec)
@@ -90,6 +153,7 @@ class MultiProgressBar @JvmOverloads constructor(
90153
isNeedRestoreProgressAfterRecreate = this@MultiProgressBar.isNeedRestoreProgressAfterRecreate
91154
singleDisplayedTime = this@MultiProgressBar.singleDisplayedTime
92155
isCompactMode = this@MultiProgressBar.isCompactMode
156+
orientation = this@MultiProgressBar.orientation
93157
}
94158
}
95159

@@ -115,10 +179,13 @@ class MultiProgressBar @JvmOverloads constructor(
115179
isProgressIsRunning = state.isProgressIsRunning
116180
singleDisplayedTime = state.singleDisplayedTime
117181
isCompactMode = state.isCompactMode
182+
orientation = state.orientation
118183

119-
if (isProgressIsRunning && isNeedRestoreProgressAfterRecreate) {
184+
if (isProgressIsRunning) {
120185
pause()
121-
internalStartProgress()
186+
if (isNeedRestoreProgressAfterRecreate) {
187+
internalStartProgress()
188+
}
122189
}
123190
}
124191

@@ -129,11 +196,23 @@ class MultiProgressBar @JvmOverloads constructor(
129196
override fun onDraw(canvas: Canvas) {
130197
for (step in 0 until countOfProgressSteps) {
131198
val previousPaddingSum = progressPadding + progressPadding * step
132-
val startX = paddingLeft + previousPaddingSum + singleProgressWidth * step
133-
val endX = if (step == countOfProgressSteps - 1) {
134-
measuredWidth - progressPadding - paddingRight
199+
val startTrack = if (orientation == Orientation.TO_RIGHT || orientation == Orientation.TO_BOTTOM) {
200+
relativePaddingStart + previousPaddingSum + singleProgressWidth * step
201+
} else {
202+
relativeLength - relativePaddingEnd - previousPaddingSum - singleProgressWidth * step
203+
}
204+
val endTrack = if (orientation == Orientation.TO_RIGHT || orientation == Orientation.TO_BOTTOM) {
205+
if (step == countOfProgressSteps - 1) {
206+
relativeLength - progressPadding - relativePaddingEnd
207+
} else {
208+
startTrack + singleProgressWidth
209+
}
135210
} else {
136-
startX + singleProgressWidth
211+
if (step == countOfProgressSteps - 1) {
212+
progressPadding + relativePaddingStart
213+
} else {
214+
startTrack - singleProgressWidth
215+
}
137216
}
138217

139218
if (step > currentAbsoluteProgress / progressPercents - 1) {
@@ -142,13 +221,49 @@ class MultiProgressBar @JvmOverloads constructor(
142221
paint.changePaintModeToProgress(isCompactMode)
143222
}
144223

145-
canvas.drawLine(startX, (measuredHeight - paddingTop - paddingBottom) / 2F + paddingTop, endX, (measuredHeight - paddingTop - paddingBottom) / 2F + paddingTop, paint)
224+
if (orientation == Orientation.TO_LEFT || orientation == Orientation.TO_RIGHT) {
225+
canvas.drawLine(
226+
startTrack,
227+
(relativeWidth - relativePaddingWidthStart - relativePaddingWidthEnd) / 2F + relativePaddingWidthStart,
228+
endTrack,
229+
(relativeWidth - relativePaddingWidthStart - relativePaddingWidthEnd) / 2F + relativePaddingWidthStart,
230+
paint
231+
)
232+
} else {
233+
canvas.drawLine(
234+
(relativeWidth - relativePaddingWidthStart - relativePaddingWidthEnd) / 2F + relativePaddingWidthStart,
235+
startTrack,
236+
(relativeWidth - relativePaddingWidthStart - relativePaddingWidthEnd) / 2F + relativePaddingWidthStart,
237+
endTrack,
238+
paint
239+
)
240+
}
146241

147242
val progressMultiplier = currentAbsoluteProgress / progressPercents - step
148243
if (progressMultiplier < 1F && progressMultiplier > 0F) {
149-
val progressEndX = startX + singleProgressWidth * progressMultiplier
244+
val progressEndX = if (orientation == Orientation.TO_RIGHT || orientation == Orientation.TO_BOTTOM) {
245+
startTrack + singleProgressWidth * progressMultiplier
246+
} else {
247+
startTrack - singleProgressWidth * progressMultiplier
248+
}
150249
paint.changePaintModeToProgress(isCompactMode)
151-
canvas.drawLine(startX, (measuredHeight - paddingTop - paddingBottom) / 2F + paddingTop, progressEndX, (measuredHeight - paddingTop - paddingBottom) / 2F + paddingTop, paint)
250+
if (orientation == Orientation.TO_LEFT || orientation == Orientation.TO_RIGHT) {
251+
canvas.drawLine(
252+
startTrack,
253+
(relativeWidth - relativePaddingWidthStart - relativePaddingWidthEnd) / 2F + relativePaddingWidthStart,
254+
progressEndX,
255+
(relativeWidth - relativePaddingWidthStart - relativePaddingWidthEnd) / 2F + relativePaddingWidthStart,
256+
paint
257+
)
258+
} else {
259+
canvas.drawLine(
260+
(relativeWidth - relativePaddingWidthStart - relativePaddingWidthEnd) / 2F + relativePaddingWidthStart,
261+
startTrack,
262+
(relativeWidth - relativePaddingWidthStart - relativePaddingWidthEnd) / 2F + relativePaddingWidthStart,
263+
progressEndX,
264+
paint
265+
)
266+
}
152267
}
153268
}
154269
}
@@ -282,9 +397,9 @@ class MultiProgressBar @JvmOverloads constructor(
282397

283398
private fun internalSetProgressStepsCount(count: Int) {
284399
countOfProgressSteps = count
285-
singleProgressWidth = (measuredWidth - progressPadding * countOfProgressSteps - progressPadding - paddingRight - paddingLeft) / countOfProgressSteps
286-
if (measuredWidth != 0 && singleProgressWidth < 0) {
287-
val compactModeSingleProgressWidth = (measuredWidth - paddingRight - paddingLeft) / countOfProgressSteps
400+
singleProgressWidth = (relativeLength - progressPadding * countOfProgressSteps - progressPadding - relativePaddingStart - relativePaddingEnd) / countOfProgressSteps
401+
if (relativeLength != 0 && singleProgressWidth < 0) {
402+
val compactModeSingleProgressWidth = (relativeLength - relativePaddingStart - relativePaddingEnd) / countOfProgressSteps
288403
if (compactModeSingleProgressWidth > 0) {
289404
progressPadding = 0F
290405
singleProgressWidth = compactModeSingleProgressWidth.toFloat()
@@ -330,6 +445,22 @@ class MultiProgressBar @JvmOverloads constructor(
330445
private const val MIN_PADDING = 8F
331446
}
332447

448+
@IntDef(
449+
Orientation.TO_TOP,
450+
Orientation.TO_RIGHT,
451+
Orientation.TO_BOTTOM,
452+
Orientation.TO_LEFT
453+
)
454+
@Retention(AnnotationRetention.SOURCE)
455+
private annotation class Orientation {
456+
companion object {
457+
const val TO_TOP = 0
458+
const val TO_RIGHT = 1
459+
const val TO_BOTTOM = 2
460+
const val TO_LEFT = 3
461+
}
462+
}
463+
333464
private class MultiProgressBarSavedState : BaseSavedState {
334465
var progressColor: Int = 0
335466
var lineColor: Int = 0
@@ -345,6 +476,7 @@ class MultiProgressBar @JvmOverloads constructor(
345476
var isNeedRestoreProgressAfterRecreate: Boolean = false
346477
var singleDisplayedTime: Float = 1F
347478
var isCompactMode: Boolean = false
479+
var orientation: Int = Orientation.TO_RIGHT
348480

349481
constructor(superState: Parcelable) : super(superState)
350482

@@ -363,6 +495,7 @@ class MultiProgressBar @JvmOverloads constructor(
363495
this.displayedStepForListener = `in`.readInt()
364496
this.singleDisplayedTime = `in`.readFloat()
365497
this.isCompactMode = `in`.readInt() == 1
498+
this.orientation = `in`.readInt()
366499
}
367500

368501
override fun writeToParcel(out: Parcel, flags: Int) {
@@ -381,6 +514,7 @@ class MultiProgressBar @JvmOverloads constructor(
381514
out.writeInt(displayedStepForListener)
382515
out.writeFloat(singleDisplayedTime)
383516
out.writeInt(if (this.isCompactMode) 1 else 0)
517+
out.writeInt(this.orientation)
384518
}
385519

386520
override fun describeContents(): Int {

multiprogressbar/src/main/res/values/attrs.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,11 @@
99
<attr name="progressPercents" format="integer"/>
1010
<attr name="isNeedRestoreProgress" format="boolean"/>
1111
<attr name="singleDisplayedTime" format="float"/>
12+
<attr name="orientation">
13+
<enum name="to_top" value="0" />
14+
<enum name="to_right" value="1" />
15+
<enum name="to_bottom" value="2" />
16+
<enum name="to_left" value="3" />
17+
</attr>
1218
</declare-styleable>
1319
</resources>

0 commit comments

Comments
 (0)