├── settings.gradle ├── screenshots └── SPB_sample.gif ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── sample ├── src │ └── main │ │ ├── res │ │ ├── drawable-hdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── values-v21 │ │ │ └── styles.xml │ │ ├── anim │ │ │ └── pocket_interpolator.xml │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ └── layout │ │ │ ├── activity_main.xml │ │ │ └── activity_custom.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── fr │ │ └── castorflex │ │ └── android │ │ └── smoothprogressbar │ │ └── sample │ │ ├── LookupTableInterpolator.java │ │ ├── MainActivity.java │ │ ├── FastOutSlowInInterpolator.java │ │ └── MakeCustomActivity.java └── build.gradle ├── library ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ ├── res │ │ ├── values-v11 │ │ │ └── styles.xml │ │ ├── values-v21 │ │ │ └── styles.xml │ │ └── values │ │ │ ├── defaults.xml │ │ │ ├── styles.xml │ │ │ ├── about_libraries_def.xml │ │ │ └── attrs.xml │ │ └── java │ │ └── fr │ │ └── castorflex │ │ └── android │ │ └── smoothprogressbar │ │ ├── ColorsShape.java │ │ ├── SmoothProgressBarUtils.java │ │ ├── ContentLoadingSmoothProgressBar.java │ │ ├── SmoothProgressBar.java │ │ └── SmoothProgressDrawable.java ├── gradle.properties └── build.gradle ├── library-circular ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ ├── res │ │ ├── values-v21 │ │ │ └── styles.xml │ │ └── values │ │ │ ├── defaults.xml │ │ │ ├── attrs.xml │ │ │ └── styles.xml │ │ └── java │ │ └── fr.castorflex.android.circularprogressbar │ │ ├── PBDelegate.java │ │ ├── SimpleAnimatorListener.java │ │ ├── Options.java │ │ ├── LookupTableInterpolator.java │ │ ├── PowerSaveModeDelegate.java │ │ ├── FastOutSlowInInterpolator.java │ │ ├── Utils.java │ │ ├── CircularProgressBar.java │ │ ├── CircularProgressDrawable.java │ │ └── DefaultDelegate.java ├── gradle.properties └── build.gradle ├── .travis.yml ├── .gitignore ├── gradle.properties ├── CHANGELOG.md ├── gradlew.bat ├── gradlew ├── README.md └── LICENSE.md /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':sample' 2 | include ':library' 3 | include ':library-circular' 4 | -------------------------------------------------------------------------------- /screenshots/SPB_sample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castorflex/SmoothProgressBar/HEAD/screenshots/SPB_sample.gif -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castorflex/SmoothProgressBar/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castorflex/SmoothProgressBar/HEAD/sample/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castorflex/SmoothProgressBar/HEAD/sample/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castorflex/SmoothProgressBar/HEAD/sample/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castorflex/SmoothProgressBar/HEAD/sample/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /library-circular/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /library-circular/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /library/src/main/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /library/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /sample/src/main/res/anim/pocket_interpolator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /library/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=SmoothProgressBar Library 2 | POM_ARTIFACT_ID=library 3 | POM_PACKAGING=aar 4 | POM_DESCRIPTION=Android Library make smooth horizontal indeterminate progress bars 5 | 6 | VERSION_NAME=1.2.0-SNAPSHOT 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | 3 | android: 4 | components: 5 | - platform-tools 6 | - tools 7 | - build-tools-26.0.0 8 | - android-25 9 | 10 | sudo: false 11 | 12 | 13 | script: ./gradlew build 14 | -------------------------------------------------------------------------------- /library-circular/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=CircularProgressBar Library 2 | POM_ARTIFACT_ID=library-circular 3 | POM_PACKAGING=aar 4 | POM_DESCRIPTION=Android Library to make smooth circular indeterminate progress bars 5 | 6 | VERSION_NAME=1.3.0 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Aug 27 15:10:58 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /sample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SmoothProgressBar 5 | 6 | 7 | Accelerate 8 | Linear 9 | AccelerateDecelerate 10 | Decelerate 11 | FastOutSlowIn 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /library-circular/src/main/res/values/defaults.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #33b5e5 4 | 4dp 5 | 20 6 | 300 7 | 1 8 | 1 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | .project 3 | .classpath 4 | .settings 5 | .checkstyle 6 | 7 | # IntelliJ IDEA 8 | .idea 9 | *.iml 10 | *.ipr 11 | *.iws 12 | classes 13 | gen-external-apklibs 14 | 15 | # Gradle 16 | .gradle 17 | build 18 | 19 | # Maven 20 | target 21 | release.properties 22 | pom.xml.* 23 | 24 | # Ant 25 | bin 26 | gen 27 | build.xml 28 | ant.properties 29 | local.properties 30 | proguard-project.txt 31 | 32 | #Crashlytics 33 | .crashlytics_data 34 | com_crashlytics_export_strings.xml 35 | 36 | # Other 37 | out/ 38 | .DS_Store 39 | tmp 40 | -------------------------------------------------------------------------------- /library-circular/src/main/java/fr.castorflex.android.circularprogressbar/PBDelegate.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.circularprogressbar; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.RectF; 6 | import android.support.annotation.UiThread; 7 | 8 | interface PBDelegate { 9 | 10 | @UiThread 11 | void draw(Canvas canvas, Paint paint); 12 | 13 | @UiThread 14 | void start(); 15 | 16 | @UiThread 17 | void stop(); 18 | 19 | @UiThread 20 | void progressiveStop(CircularProgressDrawable.OnEndListener listener); 21 | } 22 | -------------------------------------------------------------------------------- /library-circular/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion Integer.parseInt(project.COMPILE_SDK_VERSION) 5 | buildToolsVersion project.BUILD_TOOLS_VERSION 6 | 7 | defaultConfig { 8 | minSdkVersion 7 9 | targetSdkVersion 26 10 | versionName project.VERSION_NAME 11 | versionCode Integer.parseInt(project.VERSION_CODE) 12 | } 13 | 14 | lintOptions { 15 | abortOnError false 16 | } 17 | } 18 | 19 | dependencies { 20 | implementation libraries.annotations 21 | } 22 | 23 | //apply from: 'https://raw.github.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle' 24 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | VERSION_NAME=1.2.0 2 | VERSION_CODE=24 3 | BUILD_TOOLS_VERSION=26.0.1 4 | COMPILE_SDK_VERSION=26 5 | GROUP=com.github.castorflex.smoothprogressbar 6 | 7 | POM_URL=https://github.com/castorflex/SmoothProgressBar 8 | POM_SCM_URL=https://github.com/castorflex/SmoothProgressBar 9 | POM_SCM_CONNECTION=scm:git@github.com:castorflex/SmoothProgressBar.git 10 | POM_SCM_DEV_CONNECTION=scm:git@github.com:castorflex/SmoothProgressBar.git 11 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 12 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 13 | POM_LICENCE_DIST=repo 14 | POM_DEVELOPER_ID=castorflex 15 | POM_DEVELOPER_NAME=Antoine Merle 16 | 17 | -------------------------------------------------------------------------------- /library-circular/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion Integer.parseInt(project.COMPILE_SDK_VERSION) 5 | buildToolsVersion project.BUILD_TOOLS_VERSION 6 | 7 | defaultConfig { 8 | minSdkVersion 14 9 | targetSdkVersion 26 10 | versionName project.VERSION_NAME 11 | versionCode Integer.parseInt(project.VERSION_CODE) 12 | } 13 | 14 | lintOptions { 15 | abortOnError false 16 | } 17 | } 18 | 19 | dependencies { 20 | implementation libraries.annotations 21 | } 22 | 23 | //apply from: 'https://raw.github.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle' 24 | -------------------------------------------------------------------------------- /library/src/main/res/values/defaults.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #33b5e5 4 | 4dp 5 | 4dp 6 | 4 7 | 0 8 | 1 9 | false 10 | false 11 | false 12 | 13 | -------------------------------------------------------------------------------- /library-circular/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 10 | 11 | 19 | 20 | -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /library/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 9 | 19 | -------------------------------------------------------------------------------- /library-circular/src/main/java/fr.castorflex.android.circularprogressbar/SimpleAnimatorListener.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.circularprogressbar; 2 | 3 | import android.animation.Animator; 4 | import android.support.annotation.CallSuper; 5 | 6 | abstract class SimpleAnimatorListener implements Animator.AnimatorListener{ 7 | private boolean mStarted = false; 8 | private boolean mCancelled = false; 9 | 10 | @Override 11 | @CallSuper 12 | public void onAnimationStart(Animator animation) { 13 | mCancelled = false; 14 | mStarted = true; 15 | } 16 | 17 | @Override 18 | public final void onAnimationEnd(Animator animation) { 19 | onPreAnimationEnd(animation); 20 | mStarted = false; 21 | } 22 | 23 | protected void onPreAnimationEnd(Animator animation) { 24 | } 25 | 26 | @Override 27 | @CallSuper 28 | public void onAnimationCancel(Animator animation) { 29 | mCancelled = true; 30 | } 31 | 32 | @Override 33 | public void onAnimationRepeat(Animator animation) { 34 | 35 | } 36 | 37 | public boolean isStartedAndNotCancelled() { 38 | return mStarted && !mCancelled; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /library/src/main/res/values/about_libraries_def.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Antoine Merle 5 | https://github.com/castorflex 6 | SmoothProgressBar 7 | Small library allowing you to make a smooth indeterminate progress bar. You can either user your progress bars and set this drawable or use directly the SmoothProgressBarView. 8 | 1.0.0 9 | https://github.com/castorflex/SmoothProgressBar 10 | apache_2_0 11 | true 12 | https://github.com/castorflex/SmoothProgressBar.git 13 | 14 | -------------------------------------------------------------------------------- /library/src/main/java/fr/castorflex/android/smoothprogressbar/ColorsShape.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.smoothprogressbar; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.drawable.shapes.Shape; 6 | 7 | /** 8 | * Created by castorflex on 3/5/14. 9 | */ 10 | public class ColorsShape extends Shape { 11 | 12 | private float mStrokeWidth; 13 | private int[] mColors; 14 | 15 | public ColorsShape(float strokeWidth, int[] colors) { 16 | mStrokeWidth = strokeWidth; 17 | mColors = colors; 18 | } 19 | 20 | public float getStrokeWidth() { 21 | return mStrokeWidth; 22 | } 23 | 24 | public void setStrokeWidth(float strokeWidth) { 25 | mStrokeWidth = strokeWidth; 26 | } 27 | 28 | public int[] getColors() { 29 | return mColors; 30 | } 31 | 32 | public void setColors(int[] colors) { 33 | mColors = colors; 34 | } 35 | 36 | @Override 37 | public void draw(Canvas canvas, Paint paint) { 38 | float ratio = 1f / mColors.length; 39 | int i = 0; 40 | paint.setStrokeWidth(mStrokeWidth); 41 | for (int color : mColors) { 42 | paint.setColor(color); 43 | canvas.drawLine(i * ratio * getWidth(), getHeight() / 2, ++i * ratio * getWidth(), getHeight() / 2, paint); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /library-circular/src/main/java/fr.castorflex.android.circularprogressbar/Options.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.circularprogressbar; 2 | 3 | import android.view.animation.Interpolator; 4 | 5 | class Options { 6 | 7 | //params 8 | final Interpolator angleInterpolator; 9 | final Interpolator sweepInterpolator; 10 | final float borderWidth; 11 | final int[] colors; 12 | final float sweepSpeed; 13 | final float rotationSpeed; 14 | final int minSweepAngle; 15 | final int maxSweepAngle; 16 | @CircularProgressDrawable.Style final int style; 17 | 18 | Options(Interpolator angleInterpolator, 19 | Interpolator sweepInterpolator, 20 | float borderWidth, 21 | int[] colors, 22 | float sweepSpeed, 23 | float rotationSpeed, 24 | int minSweepAngle, 25 | int maxSweepAngle, 26 | @CircularProgressDrawable.Style int style) { 27 | this.angleInterpolator = angleInterpolator; 28 | this.sweepInterpolator = sweepInterpolator; 29 | this.borderWidth = borderWidth; 30 | this.colors = colors; 31 | this.sweepSpeed = sweepSpeed; 32 | this.rotationSpeed = rotationSpeed; 33 | this.minSweepAngle = minSweepAngle; 34 | this.maxSweepAngle = maxSweepAngle; 35 | this.style = style; 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /library-circular/src/main/java/fr.castorflex.android.circularprogressbar/LookupTableInterpolator.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.circularprogressbar; 2 | 3 | import android.view.animation.Interpolator; 4 | 5 | /** 6 | * Backport 7 | */ 8 | abstract class LookupTableInterpolator implements Interpolator { 9 | 10 | private final float[] mValues; 11 | private final float mStepSize; 12 | 13 | LookupTableInterpolator(float[] values) { 14 | mValues = values; 15 | mStepSize = 1f / (mValues.length - 1); 16 | } 17 | 18 | @Override 19 | public float getInterpolation(float input) { 20 | if (input >= 1.0f) { 21 | return 1.0f; 22 | } 23 | if (input <= 0f) { 24 | return 0f; 25 | } 26 | 27 | // Calculate index - We use min with length - 2 to avoid IndexOutOfBoundsException when 28 | // we lerp (linearly interpolate) in the return statement 29 | int position = Math.min((int) (input * (mValues.length - 1)), mValues.length - 2); 30 | 31 | // Calculate values to account for small offsets as the lookup table has discrete values 32 | float quantized = position * mStepSize; 33 | float diff = input - quantized; 34 | float weight = diff / mStepSize; 35 | 36 | // Linearly interpolate between the table values 37 | return mValues[position] + weight * (mValues[position + 1] - mValues[position]); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sample/src/main/java/fr/castorflex/android/smoothprogressbar/sample/LookupTableInterpolator.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.smoothprogressbar.sample; 2 | 3 | import android.view.animation.Interpolator; 4 | 5 | /** 6 | * Backport 7 | */ 8 | abstract class LookupTableInterpolator implements Interpolator { 9 | 10 | private final float[] mValues; 11 | private final float mStepSize; 12 | 13 | public LookupTableInterpolator(float[] values) { 14 | mValues = values; 15 | mStepSize = 1f / (mValues.length - 1); 16 | } 17 | 18 | @Override 19 | public float getInterpolation(float input) { 20 | if (input >= 1.0f) { 21 | return 1.0f; 22 | } 23 | if (input <= 0f) { 24 | return 0f; 25 | } 26 | 27 | // Calculate index - We use min with length - 2 to avoid IndexOutOfBoundsException when 28 | // we lerp (linearly interpolate) in the return statement 29 | int position = Math.min((int) (input * (mValues.length - 1)), mValues.length - 2); 30 | 31 | // Calculate values to account for small offsets as the lookup table has discrete values 32 | float quantized = position * mStepSize; 33 | float diff = input - quantized; 34 | float weight = diff / mStepSize; 35 | 36 | // Linearly interpolate between the table values 37 | return mValues[position] + weight * (mValues[position + 1] - mValues[position]); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion Integer.parseInt(project.COMPILE_SDK_VERSION) 5 | buildToolsVersion project.BUILD_TOOLS_VERSION 6 | 7 | defaultConfig { 8 | minSdkVersion 14 9 | targetSdkVersion 26 10 | versionName project.VERSION_NAME 11 | versionCode Integer.parseInt(project.VERSION_CODE) 12 | } 13 | 14 | signingConfigs { 15 | release 16 | } 17 | buildTypes { 18 | debug {} 19 | 20 | release { 21 | signingConfig project.hasProperty('KEYSTORE_STORE_FILE') ? signingConfigs.release : signingConfigs.debug 22 | } 23 | } 24 | 25 | lintOptions { 26 | abortOnError false 27 | } 28 | 29 | } 30 | 31 | dependencies { 32 | implementation project(':library') 33 | implementation project(':library-circular') 34 | } 35 | 36 | 37 | if (project.hasProperty('KEYSTORE_STORE_FILE')) { 38 | android.signingConfigs.release.storeFile = file(KEYSTORE_STORE_FILE) 39 | } 40 | if (project.hasProperty('KEYSTORE_KEY_ALIAS')) { 41 | android.signingConfigs.release.keyAlias = KEYSTORE_KEY_ALIAS 42 | } 43 | if (project.hasProperty('KEYSTORE_STORE_PASSWORD')) { 44 | android.signingConfigs.release.storePassword = KEYSTORE_STORE_PASSWORD 45 | } 46 | if (project.hasProperty('KEYSTORE_KEY_PASSWORD')) { 47 | android.signingConfigs.release.keyPassword = KEYSTORE_KEY_PASSWORD 48 | } 49 | -------------------------------------------------------------------------------- /library/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /library-circular/src/main/java/fr.castorflex.android.circularprogressbar/PowerSaveModeDelegate.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.circularprogressbar; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.os.SystemClock; 6 | import android.support.annotation.NonNull; 7 | 8 | import java.util.concurrent.TimeUnit; 9 | 10 | /** 11 | * Created by castorflex on 9/12/15. 12 | */ 13 | class PowerSaveModeDelegate implements PBDelegate { 14 | private static final long REFRESH_RATE = TimeUnit.SECONDS.toMillis(1L); 15 | 16 | private final CircularProgressDrawable mParent; 17 | private int mCurrentRotation; 18 | 19 | PowerSaveModeDelegate(@NonNull CircularProgressDrawable parent) { 20 | mParent = parent; 21 | } 22 | 23 | @Override 24 | public void draw(Canvas canvas, Paint paint) { 25 | canvas.drawArc(mParent.getDrawableBounds(), mCurrentRotation, 300, false, paint); 26 | } 27 | 28 | @Override 29 | public void start() { 30 | mParent.invalidate(); 31 | 32 | mParent.scheduleSelf(mRunnable, SystemClock.uptimeMillis() + REFRESH_RATE); 33 | } 34 | 35 | @Override 36 | public void stop() { 37 | mParent.unscheduleSelf(mRunnable); 38 | } 39 | 40 | @Override 41 | public void progressiveStop(CircularProgressDrawable.OnEndListener listener) { 42 | mParent.stop(); 43 | } 44 | 45 | private final Runnable mRunnable = new Runnable() { 46 | @Override 47 | public void run() { 48 | mCurrentRotation += 50; 49 | mCurrentRotation %= 360; 50 | 51 | if (mParent.isRunning()) 52 | mParent.scheduleSelf(this, SystemClock.uptimeMillis() + REFRESH_RATE); 53 | 54 | mParent.invalidate(); 55 | } 56 | }; 57 | } 58 | -------------------------------------------------------------------------------- /library/src/main/java/fr/castorflex/android/smoothprogressbar/SmoothProgressBarUtils.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.smoothprogressbar; 2 | 3 | import android.graphics.drawable.Drawable; 4 | import android.graphics.drawable.ShapeDrawable; 5 | 6 | import java.util.Locale; 7 | 8 | /** 9 | * Created by castorflex on 3/5/14. 10 | */ 11 | public final class SmoothProgressBarUtils { 12 | private SmoothProgressBarUtils() { 13 | } 14 | 15 | public static Drawable generateDrawableWithColors(int[] colors, float strokeWidth) { 16 | if (colors == null || colors.length == 0) return null; 17 | 18 | return new ShapeDrawable(new ColorsShape(strokeWidth, colors)); 19 | } 20 | 21 | static void checkSpeed(float speed) { 22 | if (speed <= 0f) 23 | throw new IllegalArgumentException("Speed must be >= 0"); 24 | } 25 | 26 | static void checkColors(int[] colors) { 27 | if (colors == null || colors.length == 0) 28 | throw new IllegalArgumentException("You must provide at least 1 color"); 29 | } 30 | 31 | static void checkAngle(int angle) { 32 | if (angle < 0 || angle > 360) 33 | throw new IllegalArgumentException(String.format(Locale.US, "Illegal angle %d: must be >=0 and <= 360", angle)); 34 | } 35 | 36 | static void checkPositiveOrZero(float number, String name) { 37 | if (number < 0) 38 | throw new IllegalArgumentException(String.format(Locale.US, "%s %d must be positive", name, number)); 39 | } 40 | 41 | static void checkPositive(int number, String name){ 42 | if(number <= 0) 43 | throw new IllegalArgumentException(String.format(Locale.US, "%s must not be null", name)); 44 | } 45 | 46 | static void checkNotNull(Object o, String name) { 47 | if (o == null) 48 | throw new IllegalArgumentException(String.format(Locale.US, "%s must be not null", name)); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.2.0 2 | 3 | - Added new `FastOutSlowInInterpolator`, enabled by default 4 | - Fixed power save mode on circular progressbar 5 | - Fixed animators stop on circular progressbar 6 | 7 | ## 1.1.0 8 | 9 | - Fixed Circular bugs (flashes) 10 | - Added material themes (mainly for determinate support) 11 | - Fixed exception bug in preview mode 12 | - **/!\\** Removed a weird 48dp height in the SmoothProgressBar style 13 | 14 | ## 1.0.0 15 | 16 | - Added CircularProgressDrawable (min API 14) 17 | 18 | ## 0.5.1 19 | 20 | - Fixed bug with gradients when reversed mode enabled and mirror mode disabled 21 | 22 | ## 0.5.0 23 | 24 | - Added a gradient option via XML and JAVA 25 | 26 | ## 0.4.0 27 | 28 | - Added a `progressStart()` and `progressStop()` methods 29 | - Added parameter `progressStart_activated` which makes the drawable to animate progressively at each start 30 | - Added speed parameters for progressStart and progressStop 31 | - Added possibility to set a background for the progressiveStart/Stop (See Pocket example) 32 | - Added possibility to set a generated background according to the bar's colors 33 | - Added a listener `progressiveStopEndedListener`: called when the progressiveStop animation is over 34 | 35 | ## 0.3.3 36 | 37 | - Added a ContentLoadingSmoothProgressBar (see also [ContentLoadingProgressBar](https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v4/java/android/support/v4/widget/ContentLoadingProgressBar.java)) 38 | 39 | ## 0.3.2 40 | 41 | - targetSdkVersion is now 14. We just need holo style. 42 | 43 | ## 0.3.1 44 | 45 | - Added a `applyStyle(int styleResId)` method 46 | 47 | ## 0.3.0 48 | 49 | - `SmoothProgressDrawable.Builder#width` is now `setStrokeWidth` 50 | - The `strokeWidth` parameter is now a `float` (was an `int`) 51 | - Added possibility to modify dynamically the `SmoothProgressBar` and `SmoothProgressDrawable` properties. 52 | e.g. You can call `mProgressBar.setColor(mColor)` 53 | -------------------------------------------------------------------------------- /sample/src/main/java/fr/castorflex/android/smoothprogressbar/sample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.smoothprogressbar.sample; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.view.animation.AccelerateInterpolator; 8 | import android.widget.ProgressBar; 9 | 10 | import fr.castorflex.android.smoothprogressbar.SmoothProgressBar; 11 | import fr.castorflex.android.smoothprogressbar.SmoothProgressBarUtils; 12 | import fr.castorflex.android.smoothprogressbar.SmoothProgressDrawable; 13 | 14 | public class MainActivity extends Activity { 15 | 16 | private ProgressBar mProgressBar1; 17 | private SmoothProgressBar mGoogleNow; 18 | private SmoothProgressBar mPocketBar; 19 | 20 | @Override 21 | protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_main); 24 | 25 | mProgressBar1 = (ProgressBar) findViewById(R.id.progressbar2); 26 | mPocketBar = (SmoothProgressBar) findViewById(R.id.pocket); 27 | 28 | mProgressBar1.setIndeterminateDrawable(new SmoothProgressDrawable.Builder(this).interpolator(new AccelerateInterpolator()).build()); 29 | 30 | mGoogleNow = (SmoothProgressBar) findViewById(R.id.google_now); 31 | mPocketBar.setSmoothProgressDrawableBackgroundDrawable( 32 | SmoothProgressBarUtils.generateDrawableWithColors( 33 | getResources().getIntArray(R.array.pocket_background_colors), 34 | ((SmoothProgressDrawable) mPocketBar.getIndeterminateDrawable()).getStrokeWidth())); 35 | 36 | findViewById(R.id.button_make).setOnClickListener(new View.OnClickListener() { 37 | @Override 38 | public void onClick(View v) { 39 | Intent intent = new Intent(MainActivity.this, MakeCustomActivity.class); 40 | startActivity(intent); 41 | } 42 | }); 43 | 44 | findViewById(R.id.start).setOnClickListener(new View.OnClickListener() { 45 | @Override 46 | public void onClick(View v) { 47 | mPocketBar.progressiveStart(); 48 | } 49 | }); 50 | 51 | findViewById(R.id.finish).setOnClickListener(new View.OnClickListener() { 52 | @Override 53 | public void onClick(View v) { 54 | mPocketBar.progressiveStop(); 55 | } 56 | }); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /sample/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @color/holo_blue_dark 5 | @color/holo_yellow_dark 6 | @color/holo_green_dark 7 | @color/holo_purple_dark 8 | @color/holo_red_dark 9 | 10 | 11 | 12 | @color/gplus_color_1 13 | @color/gplus_color_2 14 | @color/gplus_color_3 15 | @color/gplus_color_4 16 | 17 | 18 | 19 | @color/pocket_color_1 20 | @color/pocket_color_1 21 | @color/pocket_color_1 22 | @color/pocket_color_1 23 | @color/pocket_color_2 24 | @color/pocket_color_2 25 | @color/pocket_color_2 26 | @color/pocket_color_2 27 | @color/pocket_color_3 28 | @color/pocket_color_3 29 | @color/pocket_color_3 30 | @color/pocket_color_3 31 | @color/pocket_color_4 32 | @color/pocket_color_4 33 | @color/pocket_color_4 34 | @color/pocket_color_4 35 | 36 | 37 | 38 | @color/pocket_color_1 39 | @color/pocket_color_2 40 | @color/pocket_color_3 41 | @color/pocket_color_4 42 | 43 | 44 | #85edb9 45 | #34bdb7 46 | #ee4458 47 | #fcb74d 48 | 49 | #3e802f 50 | #f4b400 51 | #427fed 52 | #b23424 53 | 54 | #0099cc 55 | #ff8800 56 | #669900 57 | #9933cc 58 | #cc0000 59 | -------------------------------------------------------------------------------- /library-circular/src/main/java/fr.castorflex.android.circularprogressbar/FastOutSlowInInterpolator.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.circularprogressbar; 2 | 3 | /** 4 | * Backport 5 | */ 6 | class FastOutSlowInInterpolator extends LookupTableInterpolator { 7 | 8 | private static final float[] VALUES = new float[] { 9 | 0.0000f, 0.0001f, 0.0002f, 0.0005f, 0.0009f, 0.0014f, 0.0020f, 10 | 0.0027f, 0.0036f, 0.0046f, 0.0058f, 0.0071f, 0.0085f, 0.0101f, 11 | 0.0118f, 0.0137f, 0.0158f, 0.0180f, 0.0205f, 0.0231f, 0.0259f, 12 | 0.0289f, 0.0321f, 0.0355f, 0.0391f, 0.0430f, 0.0471f, 0.0514f, 13 | 0.0560f, 0.0608f, 0.0660f, 0.0714f, 0.0771f, 0.0830f, 0.0893f, 14 | 0.0959f, 0.1029f, 0.1101f, 0.1177f, 0.1257f, 0.1339f, 0.1426f, 15 | 0.1516f, 0.1610f, 0.1707f, 0.1808f, 0.1913f, 0.2021f, 0.2133f, 16 | 0.2248f, 0.2366f, 0.2487f, 0.2611f, 0.2738f, 0.2867f, 0.2998f, 17 | 0.3131f, 0.3265f, 0.3400f, 0.3536f, 0.3673f, 0.3810f, 0.3946f, 18 | 0.4082f, 0.4217f, 0.4352f, 0.4485f, 0.4616f, 0.4746f, 0.4874f, 19 | 0.5000f, 0.5124f, 0.5246f, 0.5365f, 0.5482f, 0.5597f, 0.5710f, 20 | 0.5820f, 0.5928f, 0.6033f, 0.6136f, 0.6237f, 0.6335f, 0.6431f, 21 | 0.6525f, 0.6616f, 0.6706f, 0.6793f, 0.6878f, 0.6961f, 0.7043f, 22 | 0.7122f, 0.7199f, 0.7275f, 0.7349f, 0.7421f, 0.7491f, 0.7559f, 23 | 0.7626f, 0.7692f, 0.7756f, 0.7818f, 0.7879f, 0.7938f, 0.7996f, 24 | 0.8053f, 0.8108f, 0.8162f, 0.8215f, 0.8266f, 0.8317f, 0.8366f, 25 | 0.8414f, 0.8461f, 0.8507f, 0.8551f, 0.8595f, 0.8638f, 0.8679f, 26 | 0.8720f, 0.8760f, 0.8798f, 0.8836f, 0.8873f, 0.8909f, 0.8945f, 27 | 0.8979f, 0.9013f, 0.9046f, 0.9078f, 0.9109f, 0.9139f, 0.9169f, 28 | 0.9198f, 0.9227f, 0.9254f, 0.9281f, 0.9307f, 0.9333f, 0.9358f, 29 | 0.9382f, 0.9406f, 0.9429f, 0.9452f, 0.9474f, 0.9495f, 0.9516f, 30 | 0.9536f, 0.9556f, 0.9575f, 0.9594f, 0.9612f, 0.9629f, 0.9646f, 31 | 0.9663f, 0.9679f, 0.9695f, 0.9710f, 0.9725f, 0.9739f, 0.9753f, 32 | 0.9766f, 0.9779f, 0.9791f, 0.9803f, 0.9815f, 0.9826f, 0.9837f, 33 | 0.9848f, 0.9858f, 0.9867f, 0.9877f, 0.9885f, 0.9894f, 0.9902f, 34 | 0.9910f, 0.9917f, 0.9924f, 0.9931f, 0.9937f, 0.9944f, 0.9949f, 35 | 0.9955f, 0.9960f, 0.9964f, 0.9969f, 0.9973f, 0.9977f, 0.9980f, 36 | 0.9984f, 0.9986f, 0.9989f, 0.9991f, 0.9993f, 0.9995f, 0.9997f, 37 | 0.9998f, 0.9999f, 0.9999f, 1.0000f, 1.0000f 38 | }; 39 | FastOutSlowInInterpolator() { 40 | super(VALUES); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sample/src/main/java/fr/castorflex/android/smoothprogressbar/sample/FastOutSlowInInterpolator.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.smoothprogressbar.sample; 2 | 3 | /** 4 | * Backport 5 | */ 6 | class FastOutSlowInInterpolator extends LookupTableInterpolator { 7 | 8 | private static final float[] VALUES = new float[] { 9 | 0.0000f, 0.0001f, 0.0002f, 0.0005f, 0.0009f, 0.0014f, 0.0020f, 10 | 0.0027f, 0.0036f, 0.0046f, 0.0058f, 0.0071f, 0.0085f, 0.0101f, 11 | 0.0118f, 0.0137f, 0.0158f, 0.0180f, 0.0205f, 0.0231f, 0.0259f, 12 | 0.0289f, 0.0321f, 0.0355f, 0.0391f, 0.0430f, 0.0471f, 0.0514f, 13 | 0.0560f, 0.0608f, 0.0660f, 0.0714f, 0.0771f, 0.0830f, 0.0893f, 14 | 0.0959f, 0.1029f, 0.1101f, 0.1177f, 0.1257f, 0.1339f, 0.1426f, 15 | 0.1516f, 0.1610f, 0.1707f, 0.1808f, 0.1913f, 0.2021f, 0.2133f, 16 | 0.2248f, 0.2366f, 0.2487f, 0.2611f, 0.2738f, 0.2867f, 0.2998f, 17 | 0.3131f, 0.3265f, 0.3400f, 0.3536f, 0.3673f, 0.3810f, 0.3946f, 18 | 0.4082f, 0.4217f, 0.4352f, 0.4485f, 0.4616f, 0.4746f, 0.4874f, 19 | 0.5000f, 0.5124f, 0.5246f, 0.5365f, 0.5482f, 0.5597f, 0.5710f, 20 | 0.5820f, 0.5928f, 0.6033f, 0.6136f, 0.6237f, 0.6335f, 0.6431f, 21 | 0.6525f, 0.6616f, 0.6706f, 0.6793f, 0.6878f, 0.6961f, 0.7043f, 22 | 0.7122f, 0.7199f, 0.7275f, 0.7349f, 0.7421f, 0.7491f, 0.7559f, 23 | 0.7626f, 0.7692f, 0.7756f, 0.7818f, 0.7879f, 0.7938f, 0.7996f, 24 | 0.8053f, 0.8108f, 0.8162f, 0.8215f, 0.8266f, 0.8317f, 0.8366f, 25 | 0.8414f, 0.8461f, 0.8507f, 0.8551f, 0.8595f, 0.8638f, 0.8679f, 26 | 0.8720f, 0.8760f, 0.8798f, 0.8836f, 0.8873f, 0.8909f, 0.8945f, 27 | 0.8979f, 0.9013f, 0.9046f, 0.9078f, 0.9109f, 0.9139f, 0.9169f, 28 | 0.9198f, 0.9227f, 0.9254f, 0.9281f, 0.9307f, 0.9333f, 0.9358f, 29 | 0.9382f, 0.9406f, 0.9429f, 0.9452f, 0.9474f, 0.9495f, 0.9516f, 30 | 0.9536f, 0.9556f, 0.9575f, 0.9594f, 0.9612f, 0.9629f, 0.9646f, 31 | 0.9663f, 0.9679f, 0.9695f, 0.9710f, 0.9725f, 0.9739f, 0.9753f, 32 | 0.9766f, 0.9779f, 0.9791f, 0.9803f, 0.9815f, 0.9826f, 0.9837f, 33 | 0.9848f, 0.9858f, 0.9867f, 0.9877f, 0.9885f, 0.9894f, 0.9902f, 34 | 0.9910f, 0.9917f, 0.9924f, 0.9931f, 0.9937f, 0.9944f, 0.9949f, 35 | 0.9955f, 0.9960f, 0.9964f, 0.9969f, 0.9973f, 0.9977f, 0.9980f, 36 | 0.9984f, 0.9986f, 0.9989f, 0.9991f, 0.9993f, 0.9995f, 0.9997f, 37 | 0.9998f, 0.9999f, 0.9999f, 1.0000f, 1.0000f 38 | }; 39 | public FastOutSlowInInterpolator() { 40 | super(VALUES); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /library-circular/src/main/java/fr.castorflex.android.circularprogressbar/Utils.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.circularprogressbar; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.annotation.TargetApi; 5 | import android.content.Context; 6 | import android.os.Build; 7 | import android.os.PowerManager; 8 | import android.support.annotation.NonNull; 9 | 10 | import java.util.Locale; 11 | 12 | import static java.lang.Math.min; 13 | 14 | class Utils { 15 | 16 | private Utils() { 17 | } 18 | 19 | static void checkSpeed(float speed) { 20 | if (speed <= 0f) 21 | throw new IllegalArgumentException("Speed must be >= 0"); 22 | } 23 | 24 | static void checkColors(int[] colors) { 25 | if (colors == null || colors.length == 0) 26 | throw new IllegalArgumentException("You must provide at least 1 color"); 27 | } 28 | 29 | static void checkAngle(int angle) { 30 | if (angle < 0 || angle > 360) 31 | throw new IllegalArgumentException(String.format(Locale.US, "Illegal angle %d: must be >=0 and <=360", angle)); 32 | } 33 | 34 | static void checkPositiveOrZero(float number, String name) { 35 | if (number < 0) 36 | throw new IllegalArgumentException(String.format(Locale.US, "%s %f must be positive", name, number)); 37 | } 38 | 39 | static void checkPositive(int number, String name) { 40 | if (number <= 0) 41 | throw new IllegalArgumentException(String.format(Locale.US, "%s must not be null", name)); 42 | } 43 | 44 | static void checkNotNull(Object o, String name) { 45 | if (o == null) 46 | throw new IllegalArgumentException(String.format(Locale.US, "%s must be not null", name)); 47 | } 48 | 49 | static float getAnimatedFraction(ValueAnimator animator) { 50 | float fraction; 51 | if (Build.VERSION.SDK_INT >= 23) { 52 | fraction = animator.getAnimatedFraction(); 53 | } else { 54 | fraction = animator.getDuration() > 0 ? ((float) animator.getCurrentPlayTime()) / animator.getDuration() : 0f; 55 | fraction = min(fraction, 1f); 56 | fraction = animator.getInterpolator().getInterpolation(fraction); 57 | } 58 | 59 | return fraction; 60 | } 61 | 62 | @TargetApi(21) 63 | static boolean isPowerSaveModeEnabled(@NonNull PowerManager powerManager) { 64 | if (Build.VERSION.SDK_INT < 21) return false; 65 | 66 | try { 67 | return powerManager.isPowerSaveMode(); 68 | } catch (Exception e) { 69 | return false; 70 | } 71 | } 72 | 73 | static PowerManager powerManager(Context context) { 74 | return (PowerManager) context.getSystemService(Context.POWER_SERVICE); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /sample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 10 | 11 | 18 | 19 | 32 | 33 | 41 | 42 | 51 | 52 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /library-circular/src/main/java/fr.castorflex.android.circularprogressbar/CircularProgressBar.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.circularprogressbar; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.content.res.TypedArray; 6 | import android.graphics.drawable.Drawable; 7 | import android.util.AttributeSet; 8 | import android.widget.ProgressBar; 9 | 10 | public class CircularProgressBar extends ProgressBar { 11 | 12 | public CircularProgressBar(Context context) { 13 | this(context, null); 14 | } 15 | 16 | public CircularProgressBar(Context context, AttributeSet attrs) { 17 | this(context, attrs, R.attr.cpbStyle); 18 | } 19 | 20 | public CircularProgressBar(Context context, AttributeSet attrs, int defStyle) { 21 | super(context, attrs, defStyle); 22 | 23 | if (isInEditMode()) { 24 | setIndeterminateDrawable(new CircularProgressDrawable.Builder(context, true).build()); 25 | return; 26 | } 27 | 28 | Resources res = context.getResources(); 29 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircularProgressBar, defStyle, 0); 30 | 31 | 32 | final int color = a.getColor(R.styleable.CircularProgressBar_cpb_color, res.getColor(R.color.cpb_default_color)); 33 | final float strokeWidth = a.getDimension(R.styleable.CircularProgressBar_cpb_stroke_width, res.getDimension(R.dimen.cpb_default_stroke_width)); 34 | final float sweepSpeed = a.getFloat(R.styleable.CircularProgressBar_cpb_sweep_speed, Float.parseFloat(res.getString(R.string.cpb_default_sweep_speed))); 35 | final float rotationSpeed = a.getFloat(R.styleable.CircularProgressBar_cpb_rotation_speed, Float.parseFloat(res.getString(R.string.cpb_default_rotation_speed))); 36 | final int colorsId = a.getResourceId(R.styleable.CircularProgressBar_cpb_colors, 0); 37 | final int minSweepAngle = a.getInteger(R.styleable.CircularProgressBar_cpb_min_sweep_angle, res.getInteger(R.integer.cpb_default_min_sweep_angle)); 38 | final int maxSweepAngle = a.getInteger(R.styleable.CircularProgressBar_cpb_max_sweep_angle, res.getInteger(R.integer.cpb_default_max_sweep_angle)); 39 | a.recycle(); 40 | 41 | int[] colors = null; 42 | //colors 43 | if (colorsId != 0) { 44 | colors = res.getIntArray(colorsId); 45 | } 46 | 47 | Drawable indeterminateDrawable; 48 | CircularProgressDrawable.Builder builder = new CircularProgressDrawable.Builder(context) 49 | .sweepSpeed(sweepSpeed) 50 | .rotationSpeed(rotationSpeed) 51 | .strokeWidth(strokeWidth) 52 | .minSweepAngle(minSweepAngle) 53 | .maxSweepAngle(maxSweepAngle); 54 | 55 | if (colors != null && colors.length > 0) 56 | builder.colors(colors); 57 | else 58 | builder.color(color); 59 | 60 | indeterminateDrawable = builder.build(); 61 | setIndeterminateDrawable(indeterminateDrawable); 62 | } 63 | 64 | private CircularProgressDrawable checkIndeterminateDrawable() { 65 | Drawable ret = getIndeterminateDrawable(); 66 | if (ret == null || !(ret instanceof CircularProgressDrawable)) 67 | throw new RuntimeException("The drawable is not a CircularProgressDrawable"); 68 | return (CircularProgressDrawable) ret; 69 | } 70 | 71 | public void progressiveStop() { 72 | checkIndeterminateDrawable().progressiveStop(); 73 | } 74 | 75 | public void progressiveStop(CircularProgressDrawable.OnEndListener listener) { 76 | checkIndeterminateDrawable().progressiveStop(listener); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /library/src/main/java/fr/castorflex/android/smoothprogressbar/ContentLoadingSmoothProgressBar.java: -------------------------------------------------------------------------------- 1 | package fr.castorflex.android.smoothprogressbar; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.View; 6 | 7 | /** 8 | * This is a copy of the ContentLoadingProgressBar from the support library, but extends 9 | * SmoothProgressBar. 10 | */ 11 | public class ContentLoadingSmoothProgressBar extends SmoothProgressBar { 12 | 13 | private static final int MIN_SHOW_TIME = 500; // ms 14 | private static final int MIN_DELAY = 500; // ms 15 | 16 | private long mStartTime = -1; 17 | 18 | private boolean mPostedHide = false; 19 | 20 | private boolean mPostedShow = false; 21 | 22 | private boolean mDismissed = false; 23 | 24 | private final Runnable mDelayedHide = new Runnable() { 25 | 26 | @Override 27 | public void run() { 28 | mPostedHide = false; 29 | mStartTime = -1; 30 | setVisibility(View.GONE); 31 | } 32 | }; 33 | 34 | private final Runnable mDelayedShow = new Runnable() { 35 | 36 | @Override 37 | public void run() { 38 | mPostedShow = false; 39 | if (!mDismissed) { 40 | mStartTime = System.currentTimeMillis(); 41 | setVisibility(View.VISIBLE); 42 | } 43 | } 44 | }; 45 | 46 | public ContentLoadingSmoothProgressBar(Context context) { 47 | this(context, null); 48 | } 49 | 50 | public ContentLoadingSmoothProgressBar(Context context, AttributeSet attrs) { 51 | super(context, attrs, 0); 52 | } 53 | 54 | @Override 55 | public void onAttachedToWindow() { 56 | super.onAttachedToWindow(); 57 | removeCallbacks(); 58 | } 59 | 60 | @Override 61 | public void onDetachedFromWindow() { 62 | super.onDetachedFromWindow(); 63 | removeCallbacks(); 64 | } 65 | 66 | private void removeCallbacks() { 67 | removeCallbacks(mDelayedHide); 68 | removeCallbacks(mDelayedShow); 69 | } 70 | 71 | /** 72 | * Hide the progress view if it is visible. The progress view will not be 73 | * hidden until it has been shown for at least a minimum show time. If the 74 | * progress view was not yet visible, cancels showing the progress view. 75 | */ 76 | public void hide() { 77 | mDismissed = true; 78 | removeCallbacks(mDelayedShow); 79 | long diff = System.currentTimeMillis() - mStartTime; 80 | if (diff >= MIN_SHOW_TIME || mStartTime == -1) { 81 | // The progress spinner has been shown long enough 82 | // OR was not shown yet. If it wasn't shown yet, 83 | // it will just never be shown. 84 | setVisibility(View.GONE); 85 | } else { 86 | // The progress spinner is shown, but not long enough, 87 | // so put a delayed message in to hide it when its been 88 | // shown long enough. 89 | if (!mPostedHide) { 90 | postDelayed(mDelayedHide, MIN_SHOW_TIME - diff); 91 | mPostedHide = true; 92 | } 93 | } 94 | } 95 | 96 | /** 97 | * Show the progress view after waiting for a minimum delay. If 98 | * during that time, hide() is called, the view is never made visible. 99 | */ 100 | public void show() { 101 | // Reset the start time. 102 | mStartTime = -1; 103 | mDismissed = false; 104 | removeCallbacks(mDelayedHide); 105 | if (!mPostedShow) { 106 | postDelayed(mDelayedShow, MIN_DELAY); 107 | mPostedShow = true; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | 17 |