diff --git a/README.md b/README.md index 6a64b7d..383da94 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,18 @@ + +> Support gradient direction from center to side by Michael Lee. `app:cpb_progressbar_color_direction` and `app:cpb_background_progressbar_color_direction` support `center_to_horizontal` or `center_to_vertical` +> Now, change the implementation to jitpack.io to use that. The release version is right here at the badge. +>[![](https://jitpack.io/v/michaellee123/CircularProgressBar.svg)](https://jitpack.io/#michaellee123/CircularProgressBar) +>After this line, is the original document.Thanks to [Lopez Mikhael](https://github.com/lopspower). + +--- +

CircularProgressBar ================= + + sample [![Platform](https://img.shields.io/badge/platform-android-green.svg)](http://developer.android.com/index.html) @@ -51,12 +61,12 @@ You must use the following properties in your XML to change your CircularProgres | `app:cpb_progressbar_color` | color | BLACK | | `app:cpb_progressbar_color_start` | color | cpb_progressbar_color | | `app:cpb_progressbar_color_end` | color | cpb_progressbar_color | -| `app:cpb_progressbar_color_direction` | left_to_right, right_to_left, top_to_bottom or bottom_to_top | left_to_right | +| `app:cpb_progressbar_color_direction` | left_to_right, right_to_left, top_to_bottom, bottom_to_top, center_to_horizontal or center_to_vertical | left_to_right | | `app:cpb_progressbar_width` | dimension | 7dp | | `app:cpb_background_progressbar_color` | color | GRAY | | `app:cpb_background_progressbar_color_start` | color | GRAY | | `app:cpb_background_progressbar_color_end` | color | GRAY | -| `app:cpb_background_progressbar_color_direction` | left_to_right, right_to_left, top_to_bottom or bottom_to_top | left_to_right | +| `app:cpb_background_progressbar_color_direction` | left_to_right, right_to_left, top_to_bottom, bottom_to_top, center_to_horizontal or center_to_vertical | | `app:cpb_background_progressbar_width` | dimension | 3dp | | `app:cpb_round_border` | boolean | false | | `app:cpb_start_angle` | float | 0f (=top) | diff --git a/build.gradle b/build.gradle index 1f81cc1..a7b66b4 100755 --- a/build.gradle +++ b/build.gradle @@ -12,6 +12,7 @@ buildscript { classpath 'com.android.tools.build:gradle:4.2.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.github.ben-manes:gradle-versions-plugin:0.38.0' + classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' } } diff --git a/circularprogressbar-example/src/main/res/layout/activity_main.xml b/circularprogressbar-example/src/main/res/layout/activity_main.xml index b2a6b37..b026020 100755 --- a/circularprogressbar-example/src/main/res/layout/activity_main.xml +++ b/circularprogressbar-example/src/main/res/layout/activity_main.xml @@ -19,11 +19,18 @@ android:id="@+id/circularProgressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" - app:cpb_background_progressbar_color="#b6bbd8" - app:cpb_background_progressbar_width="10dp" - app:cpb_progress_direction="to_right" - app:cpb_progressbar_color="#3f51b5" - app:cpb_progressbar_width="20dp" /> + app:cpb_background_progressbar_color_direction="center_to_vertical" + app:cpb_background_progressbar_color_end="#A0A8C3" + app:cpb_background_progressbar_color_start="#C0C6DF" + app:cpb_background_progressbar_width="15dp" + app:cpb_progress="100" + app:cpb_progress_direction="to_left" + app:cpb_progress_max="100" + app:cpb_progressbar_color_direction="center_to_horizontal" + app:cpb_progressbar_color_end="#6977C3" + app:cpb_progressbar_color_start="#030823" + app:cpb_progressbar_width="20dp" + app:cpb_round_border="true" /> diff --git a/circularprogressbar/build.gradle b/circularprogressbar/build.gradle index 0514545..95be9f8 100755 --- a/circularprogressbar/build.gradle +++ b/circularprogressbar/build.gradle @@ -21,3 +21,4 @@ dependencies { } apply from: rootProject.file('gradle/publish-mavencentral.gradle') +apply from: rootProject.file('gradle/publish-jitpack.gradle') diff --git a/circularprogressbar/src/main/java/com/mikhaellopez/circularprogressbar/CircularProgressBar.kt b/circularprogressbar/src/main/java/com/mikhaellopez/circularprogressbar/CircularProgressBar.kt index 7033d9f..2135316 100755 --- a/circularprogressbar/src/main/java/com/mikhaellopez/circularprogressbar/CircularProgressBar.kt +++ b/circularprogressbar/src/main/java/com/mikhaellopez/circularprogressbar/CircularProgressBar.kt @@ -56,7 +56,8 @@ class CircularProgressBar(context: Context, attrs: AttributeSet? = null) : View( requestLayout() invalidate() } - var backgroundProgressBarWidth: Float = resources.getDimension(R.dimen.default_background_stroke_width) + var backgroundProgressBarWidth: Float = + resources.getDimension(R.dimen.default_background_stroke_width) set(value) { field = value.dpToPx() backgroundPaint.strokeWidth = field @@ -172,7 +173,8 @@ class CircularProgressBar(context: Context, attrs: AttributeSet? = null) : View( if (indeterminateMode) { postIndeterminateModeHandler() // whatever you want to do below - this@CircularProgressBar.progressDirectionIndeterminateMode = this@CircularProgressBar.progressDirectionIndeterminateMode.reverse() + this@CircularProgressBar.progressDirectionIndeterminateMode = + this@CircularProgressBar.progressDirectionIndeterminateMode.reverse() if (this@CircularProgressBar.progressDirectionIndeterminateMode.isToRight()) { setProgressWithAnimation(0f, 1500) } else { @@ -192,41 +194,71 @@ class CircularProgressBar(context: Context, attrs: AttributeSet? = null) : View( private fun init(context: Context, attrs: AttributeSet?) { // Load the styled attributes and set their properties - val attributes = context.theme.obtainStyledAttributes(attrs, R.styleable.CircularProgressBar, 0, 0) + val attributes = + context.theme.obtainStyledAttributes(attrs, R.styleable.CircularProgressBar, 0, 0) // Value progress = attributes.getFloat(R.styleable.CircularProgressBar_cpb_progress, progress) - progressMax = attributes.getFloat(R.styleable.CircularProgressBar_cpb_progress_max, progressMax) + progressMax = + attributes.getFloat(R.styleable.CircularProgressBar_cpb_progress_max, progressMax) // StrokeWidth - progressBarWidth = attributes.getDimension(R.styleable.CircularProgressBar_cpb_progressbar_width, progressBarWidth).pxToDp() - backgroundProgressBarWidth = attributes.getDimension(R.styleable.CircularProgressBar_cpb_background_progressbar_width, backgroundProgressBarWidth).pxToDp() + progressBarWidth = attributes.getDimension( + R.styleable.CircularProgressBar_cpb_progressbar_width, + progressBarWidth + ).pxToDp() + backgroundProgressBarWidth = attributes.getDimension( + R.styleable.CircularProgressBar_cpb_background_progressbar_width, + backgroundProgressBarWidth + ).pxToDp() // Color - progressBarColor = attributes.getInt(R.styleable.CircularProgressBar_cpb_progressbar_color, progressBarColor) + progressBarColor = attributes.getInt( + R.styleable.CircularProgressBar_cpb_progressbar_color, + progressBarColor + ) attributes.getColor(R.styleable.CircularProgressBar_cpb_progressbar_color_start, 0) - .also { if (it != 0) progressBarColorStart = it } + .also { if (it != 0) progressBarColorStart = it } attributes.getColor(R.styleable.CircularProgressBar_cpb_progressbar_color_end, 0) - .also { if (it != 0) progressBarColorEnd = it } - progressBarColorDirection = attributes.getInteger(R.styleable.CircularProgressBar_cpb_progressbar_color_direction, progressBarColorDirection.value).toGradientDirection() - backgroundProgressBarColor = attributes.getInt(R.styleable.CircularProgressBar_cpb_background_progressbar_color, backgroundProgressBarColor) - attributes.getColor(R.styleable.CircularProgressBar_cpb_background_progressbar_color_start, 0) - .also { if (it != 0) backgroundProgressBarColorStart = it } + .also { if (it != 0) progressBarColorEnd = it } + progressBarColorDirection = attributes.getInteger( + R.styleable.CircularProgressBar_cpb_progressbar_color_direction, + progressBarColorDirection.value + ).toGradientDirection() + backgroundProgressBarColor = attributes.getInt( + R.styleable.CircularProgressBar_cpb_background_progressbar_color, + backgroundProgressBarColor + ) + attributes.getColor( + R.styleable.CircularProgressBar_cpb_background_progressbar_color_start, + 0 + ) + .also { if (it != 0) backgroundProgressBarColorStart = it } attributes.getColor(R.styleable.CircularProgressBar_cpb_background_progressbar_color_end, 0) - .also { if (it != 0) backgroundProgressBarColorEnd = it } - backgroundProgressBarColorDirection = attributes.getInteger(R.styleable.CircularProgressBar_cpb_background_progressbar_color_direction, backgroundProgressBarColorDirection.value).toGradientDirection() + .also { if (it != 0) backgroundProgressBarColorEnd = it } + backgroundProgressBarColorDirection = attributes.getInteger( + R.styleable.CircularProgressBar_cpb_background_progressbar_color_direction, + backgroundProgressBarColorDirection.value + ).toGradientDirection() // Progress Direction - progressDirection = attributes.getInteger(R.styleable.CircularProgressBar_cpb_progress_direction, progressDirection.value).toProgressDirection() + progressDirection = attributes.getInteger( + R.styleable.CircularProgressBar_cpb_progress_direction, + progressDirection.value + ).toProgressDirection() // Round Border - roundBorder = attributes.getBoolean(R.styleable.CircularProgressBar_cpb_round_border, roundBorder) + roundBorder = + attributes.getBoolean(R.styleable.CircularProgressBar_cpb_round_border, roundBorder) // Angle startAngle = attributes.getFloat(R.styleable.CircularProgressBar_cpb_start_angle, 0f) // Indeterminate Mode - indeterminateMode = attributes.getBoolean(R.styleable.CircularProgressBar_cpb_indeterminate_mode, indeterminateMode) + indeterminateMode = attributes.getBoolean( + R.styleable.CircularProgressBar_cpb_indeterminate_mode, + indeterminateMode + ) attributes.recycle() } @@ -249,13 +281,22 @@ class CircularProgressBar(context: Context, attrs: AttributeSet? = null) : View( super.onDraw(canvas) canvas.drawOval(rectF, backgroundPaint) - val realProgress = (if (indeterminateMode) progressIndeterminateMode else progress) * DEFAULT_MAX_VALUE / progressMax + val realProgress = + (if (indeterminateMode) progressIndeterminateMode else progress) * DEFAULT_MAX_VALUE / progressMax - val isToRightFromIndeterminateMode = indeterminateMode && progressDirectionIndeterminateMode.isToRight() + val isToRightFromIndeterminateMode = + indeterminateMode && progressDirectionIndeterminateMode.isToRight() val isToRightFromNormalMode = !indeterminateMode && progressDirection.isToRight() - val angle = (if (isToRightFromIndeterminateMode || isToRightFromNormalMode) 360 else -360) * realProgress / 100 - - canvas.drawArc(rectF, if (indeterminateMode) startAngleIndeterminateMode else startAngle, angle, false, foregroundPaint) + val angle = + (if (isToRightFromIndeterminateMode || isToRightFromNormalMode) 360 else -360) * realProgress / 100 + + canvas.drawArc( + rectF, + if (indeterminateMode) startAngleIndeterminateMode else startAngle, + angle, + false, + foregroundPaint + ) } override fun setBackgroundColor(backgroundColor: Int) { @@ -263,18 +304,25 @@ class CircularProgressBar(context: Context, attrs: AttributeSet? = null) : View( } private fun manageColor() { - foregroundPaint.shader = createLinearGradient(progressBarColorStart ?: progressBarColor, - progressBarColorEnd ?: progressBarColor, progressBarColorDirection) + foregroundPaint.shader = createLinearGradient( + progressBarColorStart ?: progressBarColor, + progressBarColorEnd ?: progressBarColor, progressBarColorDirection + ) } private fun manageBackgroundProgressBarColor() { backgroundPaint.shader = createLinearGradient( - backgroundProgressBarColorStart ?: backgroundProgressBarColor, - backgroundProgressBarColorEnd ?: backgroundProgressBarColor, - backgroundProgressBarColorDirection) + backgroundProgressBarColorStart ?: backgroundProgressBarColor, + backgroundProgressBarColorEnd ?: backgroundProgressBarColor, + backgroundProgressBarColorDirection + ) } - private fun createLinearGradient(startColor: Int, endColor: Int, gradientDirection: GradientDirection): LinearGradient { + private fun createLinearGradient( + startColor: Int, + endColor: Int, + gradientDirection: GradientDirection, + ): LinearGradient { var x0 = 0f var y0 = 0f var x1 = 0f @@ -284,8 +332,14 @@ class CircularProgressBar(context: Context, attrs: AttributeSet? = null) : View( GradientDirection.RIGHT_TO_LEFT -> x0 = width.toFloat() GradientDirection.TOP_TO_BOTTOM -> y1 = height.toFloat() GradientDirection.BOTTOM_TO_END -> y0 = height.toFloat() + GradientDirection.CENTER_TO_HORIZONTAL -> x0 = width.toFloat() / 2 + GradientDirection.CENTER_TO_VERTICAL -> y0 = height.toFloat() / 2 + } + val mode = when (gradientDirection) { + GradientDirection.CENTER_TO_HORIZONTAL, GradientDirection.CENTER_TO_VERTICAL -> Shader.TileMode.MIRROR + else -> Shader.TileMode.CLAMP } - return LinearGradient(x0, y0, x1, y1, startColor, endColor, Shader.TileMode.CLAMP) + return LinearGradient(x0, y0, x1, y1, startColor, endColor, mode) } //endregion @@ -295,8 +349,14 @@ class CircularProgressBar(context: Context, attrs: AttributeSet? = null) : View( val width = getDefaultSize(suggestedMinimumWidth, widthMeasureSpec) val min = min(width, height) setMeasuredDimension(min, min) - val highStroke = if (progressBarWidth > backgroundProgressBarWidth) progressBarWidth else backgroundProgressBarWidth - rectF.set(0 + highStroke / 2, 0 + highStroke / 2, min - highStroke / 2, min - highStroke / 2) + val highStroke = + if (progressBarWidth > backgroundProgressBarWidth) progressBarWidth else backgroundProgressBarWidth + rectF.set( + 0 + highStroke / 2, + 0 + highStroke / 2, + min - highStroke / 2, + min - highStroke / 2 + ) } //endregion @@ -309,12 +369,17 @@ class CircularProgressBar(context: Context, attrs: AttributeSet? = null) : View( * @param startDelay [Long] optional, null by default. */ @JvmOverloads - fun setProgressWithAnimation(progress: Float, - duration: Long? = null, - interpolator: TimeInterpolator? = null, - startDelay: Long? = null) { + fun setProgressWithAnimation( + progress: Float, + duration: Long? = null, + interpolator: TimeInterpolator? = null, + startDelay: Long? = null + ) { progressAnimator?.cancel() - progressAnimator = ValueAnimator.ofFloat(if (indeterminateMode) progressIndeterminateMode else this.progress, progress) + progressAnimator = ValueAnimator.ofFloat( + if (indeterminateMode) progressIndeterminateMode else this.progress, + progress + ) duration?.also { progressAnimator?.duration = it } interpolator?.also { progressAnimator?.interpolator = it } startDelay?.also { progressAnimator?.startDelay = it } @@ -333,31 +398,33 @@ class CircularProgressBar(context: Context, attrs: AttributeSet? = null) : View( //region Extensions Utils private fun Float.dpToPx(): Float = - this * Resources.getSystem().displayMetrics.density + this * Resources.getSystem().displayMetrics.density private fun Float.pxToDp(): Float = - this / Resources.getSystem().displayMetrics.density + this / Resources.getSystem().displayMetrics.density private fun Int.toProgressDirection(): ProgressDirection = - when (this) { - 1 -> ProgressDirection.TO_RIGHT - 2 -> ProgressDirection.TO_LEFT - else -> throw IllegalArgumentException("This value is not supported for ProgressDirection: $this") - } + when (this) { + 1 -> ProgressDirection.TO_RIGHT + 2 -> ProgressDirection.TO_LEFT + else -> throw IllegalArgumentException("This value is not supported for ProgressDirection: $this") + } private fun ProgressDirection.reverse(): ProgressDirection = - if (this.isToRight()) ProgressDirection.TO_LEFT else ProgressDirection.TO_RIGHT + if (this.isToRight()) ProgressDirection.TO_LEFT else ProgressDirection.TO_RIGHT private fun ProgressDirection.isToRight(): Boolean = this == ProgressDirection.TO_RIGHT private fun Int.toGradientDirection(): GradientDirection = - when (this) { - 1 -> GradientDirection.LEFT_TO_RIGHT - 2 -> GradientDirection.RIGHT_TO_LEFT - 3 -> GradientDirection.TOP_TO_BOTTOM - 4 -> GradientDirection.BOTTOM_TO_END - else -> throw IllegalArgumentException("This value is not supported for GradientDirection: $this") - } + when (this) { + 1 -> GradientDirection.LEFT_TO_RIGHT + 2 -> GradientDirection.RIGHT_TO_LEFT + 3 -> GradientDirection.TOP_TO_BOTTOM + 4 -> GradientDirection.BOTTOM_TO_END + 5 -> GradientDirection.CENTER_TO_HORIZONTAL + 6 -> GradientDirection.CENTER_TO_VERTICAL + else -> throw IllegalArgumentException("This value is not supported for GradientDirection: $this") + } //endregion /** @@ -375,7 +442,9 @@ class CircularProgressBar(context: Context, attrs: AttributeSet? = null) : View( LEFT_TO_RIGHT(1), RIGHT_TO_LEFT(2), TOP_TO_BOTTOM(3), - BOTTOM_TO_END(4) + BOTTOM_TO_END(4), + CENTER_TO_HORIZONTAL(5), + CENTER_TO_VERTICAL(6) } } diff --git a/circularprogressbar/src/main/res/values/attrs.xml b/circularprogressbar/src/main/res/values/attrs.xml index 62e8321..8b6c2dd 100755 --- a/circularprogressbar/src/main/res/values/attrs.xml +++ b/circularprogressbar/src/main/res/values/attrs.xml @@ -11,6 +11,8 @@ + + @@ -20,6 +22,8 @@ + + diff --git a/gradle/publish-jitpack.gradle b/gradle/publish-jitpack.gradle new file mode 100644 index 0000000..ddfc7f2 --- /dev/null +++ b/gradle/publish-jitpack.gradle @@ -0,0 +1,2 @@ +apply plugin: 'com.github.dcendents.android-maven' +group='com.github.michaellee123' \ No newline at end of file diff --git a/gradle/publish-mavencentral.gradle b/gradle/publish-mavencentral.gradle index 3fa7e75..71b6ca9 100644 --- a/gradle/publish-mavencentral.gradle +++ b/gradle/publish-mavencentral.gradle @@ -1,94 +1,94 @@ -apply plugin: 'maven' -apply plugin: 'maven-publish' -apply plugin: 'signing' - -// Because the components are created only during the afterEvaluate phase, you must -// configure your publications using the afterEvaluate() lifecycle method. -afterEvaluate { - publishing { - publications { - // Creates a Maven publication called "release". - release(MavenPublication) { - // Applies the component for the release build variant. - from components.release - - // You can then customize attributes of the publication as shown below. - groupId = libraryGroupId - artifactId = libraryArtifactId - version = libraryVersion - } - // Creates a Maven publication called “debug”. - debug(MavenPublication) { - // Applies the component for the debug build variant. - from components.debug - - groupId = libraryGroupId - artifactId = libraryArtifactId - version = libraryVersion - } - } - } - - uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { deployment -> signing.signPom(deployment) } - - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - - snapshotRepository(url: "https:/oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - - pom.project { - name 'CircularProgressBar' - packaging 'aar' - // optionally artifactId can be defined here - description 'This is an Android project allowing to realize a circular ProgressBar in the simplest way possible.' - url 'https://github.com/lopspower/CircularProgressBar' - - groupId = libraryGroupId - artifactId = libraryArtifactId - version = libraryVersion - - scm { - connection 'scm:git:https://github.com/lopspower/CircularProgressBar' - developerConnection 'scm:git:https://github.com/lopspower/CircularProgressBar' - url 'https://github.com/lopspower/CircularProgressBar' - } - - licenses { - license { - name 'The Apache License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - } - } - - developers { - developer { - id 'mikhael.lopez' - name 'Mikhael LOPEZ' - email 'lopez.mikhael@gmail.com' - } - } - } - } - } - } - - task androidSourcesJar(type: Jar) { - archiveClassifier.set('sources') - from android.sourceSets.main.java.sourceFiles - } - - signing { - required { gradle.taskGraph.hasTask("uploadArchives") } - sign configurations.archives - } - - artifacts { - archives androidSourcesJar - } -} \ No newline at end of file +//apply plugin: 'maven' +//apply plugin: 'maven-publish' +//apply plugin: 'signing' +// +//// Because the components are created only during the afterEvaluate phase, you must +//// configure your publications using the afterEvaluate() lifecycle method. +//afterEvaluate { +// publishing { +// publications { +// // Creates a Maven publication called "release". +// release(MavenPublication) { +// // Applies the component for the release build variant. +// from components.release +// +// // You can then customize attributes of the publication as shown below. +// groupId = libraryGroupId +// artifactId = libraryArtifactId +// version = libraryVersion +// } +// // Creates a Maven publication called “debug”. +// debug(MavenPublication) { +// // Applies the component for the debug build variant. +// from components.debug +// +// groupId = libraryGroupId +// artifactId = libraryArtifactId +// version = libraryVersion +// } +// } +// } +// +// uploadArchives { +// repositories { +// mavenDeployer { +// beforeDeployment { deployment -> signing.signPom(deployment) } +// +// repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { +// authentication(userName: ossrhUsername, password: ossrhPassword) +// } +// +// snapshotRepository(url: "https:/oss.sonatype.org/content/repositories/snapshots/") { +// authentication(userName: ossrhUsername, password: ossrhPassword) +// } +// +// pom.project { +// name 'CircularProgressBar' +// packaging 'aar' +// // optionally artifactId can be defined here +// description 'This is an Android project allowing to realize a circular ProgressBar in the simplest way possible.' +// url 'https://github.com/lopspower/CircularProgressBar' +// +// groupId = libraryGroupId +// artifactId = libraryArtifactId +// version = libraryVersion +// +// scm { +// connection 'scm:git:https://github.com/lopspower/CircularProgressBar' +// developerConnection 'scm:git:https://github.com/lopspower/CircularProgressBar' +// url 'https://github.com/lopspower/CircularProgressBar' +// } +// +// licenses { +// license { +// name 'The Apache License, Version 2.0' +// url 'http://www.apache.org/licenses/LICENSE-2.0.txt' +// } +// } +// +// developers { +// developer { +// id 'mikhael.lopez' +// name 'Mikhael LOPEZ' +// email 'lopez.mikhael@gmail.com' +// } +// } +// } +// } +// } +// } +// +// task androidSourcesJar(type: Jar) { +// archiveClassifier.set('sources') +// from android.sourceSets.main.java.sourceFiles +// } +// +// signing { +// required { gradle.taskGraph.hasTask("uploadArchives") } +// sign configurations.archives +// } +// +// artifacts { +// archives androidSourcesJar +// } +//} \ No newline at end of file