3 | * All Rights Reserved.
4 | */
5 |
6 | package me.zhanghai.android.materialprogressbar;
7 |
8 | import android.content.res.ColorStateList;
9 | import android.graphics.ColorFilter;
10 | import android.graphics.PorterDuff;
11 | import android.graphics.drawable.Drawable;
12 |
13 | import androidx.annotation.ColorInt;
14 | import androidx.annotation.NonNull;
15 | import androidx.annotation.Nullable;
16 | import androidx.core.graphics.drawable.TintAwareDrawable;
17 |
18 | /**
19 | * A {@code Drawable} that is tintable.
20 | */
21 | public interface TintableDrawable extends TintAwareDrawable {
22 |
23 | /**
24 | * Specifies tint color for this drawable.
25 | *
26 | * A Drawable's drawing content will be blended together with its tint
27 | * before it is drawn to the screen. This functions similarly to
28 | * {@link Drawable#setColorFilter(int, PorterDuff.Mode)}.
29 | *
30 | *
31 | * To clear the tint, pass {@code null} to
32 | * {@link #setTintList(ColorStateList)}.
33 | *
34 | * Note: Setting a color filter via
35 | * {@link Drawable#setColorFilter(ColorFilter)} or
36 | * {@link Drawable#setColorFilter(int, PorterDuff.Mode)} overrides tint.
37 | *
38 | *
39 | * @param tintColor Color to use for tinting this drawable
40 | * @see #setTintList(ColorStateList)
41 | * @see #setTintMode(PorterDuff.Mode)
42 | */
43 | void setTint(@ColorInt int tintColor);
44 |
45 | /**
46 | * Specifies tint color for this drawable as a color state list.
47 | *
48 | * A Drawable's drawing content will be blended together with its tint
49 | * before it is drawn to the screen. This functions similarly to
50 | * {@link Drawable#setColorFilter(int, PorterDuff.Mode)}.
51 | *
52 | * Note: Setting a color filter via
53 | * {@link Drawable#setColorFilter(ColorFilter)} or
54 | * {@link Drawable#setColorFilter(int, PorterDuff.Mode)} overrides tint.
55 | *
56 | *
57 | * @param tint Color state list to use for tinting this drawable, or
58 | * {@code null} to clear the tint
59 | * @see #setTint(int)
60 | * @see #setTintMode(PorterDuff.Mode)
61 | */
62 | void setTintList(@Nullable ColorStateList tint);
63 |
64 | /**
65 | * Specifies a tint blending mode for this drawable.
66 | *
67 | * Defines how this drawable's tint color should be blended into the drawable
68 | * before it is drawn to screen. Default tint mode is {@link PorterDuff.Mode#SRC_IN}.
69 | *
70 | * Note: Setting a color filter via
71 | * {@link Drawable#setColorFilter(ColorFilter)} or
72 | * {@link Drawable#setColorFilter(int, PorterDuff.Mode)} overrides tint.
73 | *
74 | *
75 | * @param tintMode A Porter-Duff blending mode
76 | * @see #setTint(int)
77 | * @see #setTintList(ColorStateList)
78 | */
79 | void setTintMode(@NonNull PorterDuff.Mode tintMode);
80 | }
81 |
--------------------------------------------------------------------------------
/library/src/main/java/me/zhanghai/android/materialprogressbar/internal/AnimationScaleListDrawableCompat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package me.zhanghai.android.materialprogressbar.internal;
18 |
19 | import android.content.res.Resources;
20 | import android.graphics.drawable.Animatable;
21 | import android.graphics.drawable.Drawable;
22 | import android.os.Build;
23 |
24 | import androidx.annotation.NonNull;
25 | import androidx.annotation.Nullable;
26 | import androidx.annotation.RequiresApi;
27 |
28 | /*
29 | * @see com.android.internal.graphics.drawable.AnimationScaleListDrawable
30 | */
31 | public class AnimationScaleListDrawableCompat extends DrawableContainerCompat
32 | implements Animatable {
33 | private static final String TAG = "AnimationScaleListDrawableCompat";
34 | private AnimationScaleListState mAnimationScaleListState;
35 | private boolean mMutated;
36 |
37 | public AnimationScaleListDrawableCompat(@NonNull Drawable[] drawables) {
38 | setConstantState(new AnimationScaleListState(null, this, null));
39 | for (Drawable drawable : drawables) {
40 | mAnimationScaleListState.addDrawable(drawable);
41 | }
42 | onStateChange(getState());
43 | }
44 |
45 | private AnimationScaleListDrawableCompat(@Nullable AnimationScaleListState state,
46 | @Nullable Resources res) {
47 | // Every scale list drawable has its own constant state.
48 | final AnimationScaleListState newState = new AnimationScaleListState(state, this, res);
49 | setConstantState(newState);
50 | onStateChange(getState());
51 | }
52 |
53 | /**
54 | * Set the current drawable according to the animation scale. If scale is 0, then pick the
55 | * static drawable, otherwise, pick the animatable drawable.
56 | */
57 | @Override
58 | protected boolean onStateChange(int[] stateSet) {
59 | final boolean changed = super.onStateChange(stateSet);
60 | int idx = mAnimationScaleListState.getCurrentDrawableIndexBasedOnScale();
61 | return selectDrawable(idx) || changed;
62 | }
63 |
64 |
65 | @Override
66 | public Drawable mutate() {
67 | if (!mMutated && super.mutate() == this) {
68 | mAnimationScaleListState.mutate();
69 | mMutated = true;
70 | }
71 | return this;
72 | }
73 |
74 | @Override
75 | public void clearMutated() {
76 | super.clearMutated();
77 | mMutated = false;
78 | }
79 |
80 | @Override
81 | public void start() {
82 | Drawable dr = getCurrent();
83 | if (dr != null && dr instanceof Animatable) {
84 | ((Animatable) dr).start();
85 | }
86 | }
87 |
88 | @Override
89 | public void stop() {
90 | Drawable dr = getCurrent();
91 | if (dr != null && dr instanceof Animatable) {
92 | ((Animatable) dr).stop();
93 | }
94 | }
95 |
96 | @Override
97 | public boolean isRunning() {
98 | boolean result = false;
99 | Drawable dr = getCurrent();
100 | if (dr != null && dr instanceof Animatable) {
101 | result = ((Animatable) dr).isRunning();
102 | }
103 | return result;
104 | }
105 |
106 | static class AnimationScaleListState extends DrawableContainerState {
107 | int[] mThemeAttrs = null;
108 | // The index of the last static drawable.
109 | int mStaticDrawableIndex = -1;
110 | // The index of the last animatable drawable.
111 | int mAnimatableDrawableIndex = -1;
112 |
113 | AnimationScaleListState(AnimationScaleListState orig,
114 | AnimationScaleListDrawableCompat owner, Resources res) {
115 | super(orig, owner, res);
116 |
117 | if (orig != null) {
118 | // Perform a shallow copy and rely on mutate() to deep-copy.
119 | mThemeAttrs = orig.mThemeAttrs;
120 |
121 | mStaticDrawableIndex = orig.mStaticDrawableIndex;
122 | mAnimatableDrawableIndex = orig.mAnimatableDrawableIndex;
123 | }
124 |
125 | }
126 |
127 | void mutate() {
128 | mThemeAttrs = mThemeAttrs != null ? mThemeAttrs.clone() : null;
129 | }
130 |
131 | /**
132 | * Add the drawable into the container.
133 | * This class only keep track one animatable drawable, and one static. If there are multiple
134 | * defined in the XML, then pick the last one.
135 | */
136 | int addDrawable(Drawable drawable) {
137 | final int pos = addChild(drawable);
138 | if (drawable instanceof Animatable) {
139 | mAnimatableDrawableIndex = pos;
140 | } else {
141 | mStaticDrawableIndex = pos;
142 | }
143 | return pos;
144 | }
145 |
146 | @Override
147 | public Drawable newDrawable() {
148 | return new AnimationScaleListDrawableCompat(this, null);
149 | }
150 |
151 | @Override
152 | public Drawable newDrawable(Resources res) {
153 | return new AnimationScaleListDrawableCompat(this, res);
154 | }
155 |
156 | @Override
157 | @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
158 | public boolean canApplyTheme() {
159 | return mThemeAttrs != null || super.canApplyTheme();
160 | }
161 |
162 | public int getCurrentDrawableIndexBasedOnScale() {
163 | if (!ValueAnimatorCompat.areAnimatorsEnabled()) {
164 | return mStaticDrawableIndex;
165 | }
166 | return mAnimatableDrawableIndex;
167 | }
168 | }
169 |
170 | @Override
171 | @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
172 | public void applyTheme(@NonNull Resources.Theme theme) {
173 | super.applyTheme(theme);
174 |
175 | onStateChange(getState());
176 | }
177 |
178 | @Override
179 | protected void setConstantState(@NonNull DrawableContainerState state) {
180 | super.setConstantState(state);
181 |
182 | if (state instanceof AnimationScaleListState) {
183 | mAnimationScaleListState = (AnimationScaleListState) state;
184 | }
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/library/src/main/java/me/zhanghai/android/materialprogressbar/internal/DrawableCompat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Zhang Hai
3 | * All Rights Reserved.
4 | */
5 |
6 | package me.zhanghai.android.materialprogressbar.internal;
7 |
8 | import android.graphics.PorterDuff;
9 |
10 | import androidx.annotation.Nullable;
11 |
12 | public class DrawableCompat {
13 |
14 | /**
15 | * Parses a {@link android.graphics.PorterDuff.Mode} from a tintMode attribute's enum value.
16 | */
17 | public static @Nullable PorterDuff.Mode parseTintMode(int value,
18 | @Nullable PorterDuff.Mode defaultMode) {
19 | switch (value) {
20 | case 3: return PorterDuff.Mode.SRC_OVER;
21 | case 5: return PorterDuff.Mode.SRC_IN;
22 | case 9: return PorterDuff.Mode.SRC_ATOP;
23 | case 14: return PorterDuff.Mode.MULTIPLY;
24 | case 15: return PorterDuff.Mode.SCREEN;
25 | case 16: return PorterDuff.Mode.ADD;
26 | default: return defaultMode;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/library/src/main/java/me/zhanghai/android/materialprogressbar/internal/ObjectAnimatorCompat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Zhang Hai
3 | * All Rights Reserved.
4 | */
5 |
6 | package me.zhanghai.android.materialprogressbar.internal;
7 |
8 | import android.animation.ObjectAnimator;
9 | import android.graphics.Path;
10 | import android.os.Build;
11 | import android.util.Property;
12 |
13 | import androidx.annotation.NonNull;
14 | import androidx.annotation.Nullable;
15 |
16 | /**
17 | * Helper for accessing features in {@link ObjectAnimator} introduced after API level 11 (for
18 | * {@link android.animation.PropertyValuesHolder}) in a backward compatible fashion.
19 | */
20 | public class ObjectAnimatorCompat {
21 |
22 | private ObjectAnimatorCompat() {}
23 |
24 | /**
25 | * Constructs and returns an ObjectAnimator that animates between color values. A single
26 | * value implies that that value is the one being animated to. Two values imply starting
27 | * and ending values. More than two values imply a starting value, values to animate through
28 | * along the way, and an ending value (these values will be distributed evenly across
29 | * the duration of the animation).
30 | *
31 | * @param target The object whose property is to be animated. This object should have a public
32 | * method on it called {@code setName()}, where {@code name} is the value of the
33 | * {@code propertyName} parameter.
34 | * @param propertyName The name of the property being animated.
35 | * @param values A set of values that the animation will animate between over time.
36 | * @return An ObjectAnimator object that is set up to animate between the given values.
37 | */
38 | @NonNull
39 | public static ObjectAnimator ofArgb(@Nullable Object target, @NonNull String propertyName,
40 | int... values) {
41 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
42 | return ObjectAnimatorCompatLollipop.ofArgb(target, propertyName, values);
43 | } else {
44 | return ObjectAnimatorCompatBase.ofArgb(target, propertyName, values);
45 | }
46 | }
47 |
48 | /**
49 | * Constructs and returns an ObjectAnimator that animates between color values. A single
50 | * value implies that that value is the one being animated to. Two values imply starting
51 | * and ending values. More than two values imply a starting value, values to animate through
52 | * along the way, and an ending value (these values will be distributed evenly across
53 | * the duration of the animation).
54 | *
55 | * @param target The object whose property is to be animated.
56 | * @param property The property being animated.
57 | * @param values A set of values that the animation will animate between over time.
58 | * @return An ObjectAnimator object that is set up to animate between the given values.
59 | */
60 | @NonNull
61 | public static ObjectAnimator ofArgb(@Nullable T target,
62 | @NonNull Property property, int... values) {
63 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
64 | return ObjectAnimatorCompatLollipop.ofArgb(target, property, values);
65 | } else {
66 | return ObjectAnimatorCompatBase.ofArgb(target, property, values);
67 | }
68 | }
69 |
70 | /**
71 | * Constructs and returns an ObjectAnimator that animates coordinates along a {@code Path} using
72 | * two properties. A {@code Path} animation moves in two dimensions, animating coordinates
73 | * {@code (x, y)} together to follow the line. In this variation, the coordinates are floats
74 | * that are set to separate properties designated by {@code xPropertyName} and
75 | * {@code yPropertyName}.
76 | *
77 | * @param target The object whose properties are to be animated. This object should have public
78 | * methods on it called {@code setNameX()} and {@code setNameY}, where
79 | * {@code nameX} and {@code nameY} are the value of the {@code xPropertyName} and
80 | * {@code yPropertyName} parameters, respectively.
81 | * @param xPropertyName The name of the property for the x coordinate being animated.
82 | * @param yPropertyName The name of the property for the y coordinate being animated.
83 | * @param path The {@code Path} to animate values along.
84 | * @return An ObjectAnimator object that is set up to animate along {@code path}.
85 | */
86 | @NonNull
87 | public static ObjectAnimator ofFloat(@Nullable Object target, @NonNull String xPropertyName,
88 | @NonNull String yPropertyName, @NonNull Path path) {
89 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
90 | return ObjectAnimatorCompatLollipop.ofFloat(target, xPropertyName, yPropertyName, path);
91 | } else {
92 | return ObjectAnimatorCompatBase.ofFloat(target, xPropertyName, yPropertyName, path);
93 | }
94 | }
95 |
96 | /**
97 | * Constructs and returns an ObjectAnimator that animates coordinates along a {@code Path} using
98 | * two properties. A {@code Path} animation moves in two dimensions, animating coordinates
99 | * {@code (x, y)} together to follow the line. In this variation, the coordinates are floats
100 | * that are set to separate properties, {@code xProperty} and {@code yProperty}.
101 | *
102 | * @param target The object whose properties are to be animated.
103 | * @param xProperty The property for the x coordinate being animated.
104 | * @param yProperty The property for the y coordinate being animated.
105 | * @param path The {@code Path} to animate values along.
106 | * @return An ObjectAnimator object that is set up to animate along {@code path}.
107 | */
108 | @NonNull
109 | public static ObjectAnimator ofFloat(@Nullable T target,
110 | @NonNull Property xProperty,
111 | @NonNull Property yProperty,
112 | @NonNull Path path) {
113 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
114 | return ObjectAnimatorCompatLollipop.ofFloat(target, xProperty, yProperty, path);
115 | } else {
116 | return ObjectAnimatorCompatBase.ofFloat(target, xProperty, yProperty, path);
117 | }
118 | }
119 |
120 | /**
121 | * Constructs and returns an ObjectAnimator that animates coordinates along a {@code Path} using
122 | * two properties. A {@code Path} animation moves in two dimensions, animating coordinates
123 | * {@code (x, y)} together to follow the line. In this variation, the coordinates are integers
124 | * that are set to separate properties designated by {@code xPropertyName} and
125 | * {@code yPropertyName}.
126 | *
127 | * @param target The object whose properties are to be animated. This object should have public
128 | * methods on it called {@code setNameX()} and {@code setNameY}, where
129 | * {@code nameX} and {@code nameY} are the value of {@code xPropertyName} and
130 | * {@code yPropertyName} parameters, respectively.
131 | * @param xPropertyName The name of the property for the x coordinate being animated.
132 | * @param yPropertyName The name of the property for the y coordinate being animated.
133 | * @param path The {@code Path} to animate values along.
134 | * @return An ObjectAnimator object that is set up to animate along {@code path}.
135 | */
136 | @NonNull
137 | public static ObjectAnimator ofInt(@Nullable Object target, @NonNull String xPropertyName,
138 | @NonNull String yPropertyName, @NonNull Path path) {
139 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
140 | return ObjectAnimatorCompatLollipop.ofInt(target, xPropertyName, yPropertyName, path);
141 | } else {
142 | return ObjectAnimatorCompatBase.ofInt(target, xPropertyName, yPropertyName, path);
143 | }
144 | }
145 |
146 | /**
147 | * Constructs and returns an ObjectAnimator that animates coordinates along a {@code Path} using
148 | * two properties. A {@code Path} animation moves in two dimensions, animating coordinates
149 | * {@code (x, y)} together to follow the line. In this variation, the coordinates are integers
150 | * that are set to separate properties, {@code xProperty} and {@code yProperty}.
151 | *
152 | * @param target The object whose properties are to be animated.
153 | * @param xProperty The property for the x coordinate being animated.
154 | * @param yProperty The property for the y coordinate being animated.
155 | * @param path The {@code Path} to animate values along.
156 | * @return An ObjectAnimator object that is set up to animate along {@code path}.
157 | */
158 | @NonNull
159 | public static ObjectAnimator ofInt(@Nullable T target,
160 | @NonNull Property xProperty,
161 | @NonNull Property yProperty,
162 | @NonNull Path path) {
163 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
164 | return ObjectAnimatorCompatLollipop.ofInt(target, xProperty, yProperty, path);
165 | } else {
166 | return ObjectAnimatorCompatBase.ofInt(target, xProperty, yProperty, path);
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/library/src/main/java/me/zhanghai/android/materialprogressbar/internal/ObjectAnimatorCompatBase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Zhang Hai
3 | * All Rights Reserved.
4 | */
5 |
6 | package me.zhanghai.android.materialprogressbar.internal;
7 |
8 | import android.animation.ArgbEvaluator;
9 | import android.animation.ObjectAnimator;
10 | import android.animation.PropertyValuesHolder;
11 | import android.graphics.Path;
12 | import android.graphics.PathMeasure;
13 | import android.util.Property;
14 |
15 | import androidx.annotation.NonNull;
16 | import androidx.annotation.Nullable;
17 | import androidx.annotation.Size;
18 |
19 | class ObjectAnimatorCompatBase {
20 |
21 | // As per android.support.v4.view.animation.FastOutLinearInInterpolator.
22 | private static final int NUM_POINTS = 201;
23 |
24 | private ObjectAnimatorCompatBase() {}
25 |
26 | @NonNull
27 | public static ObjectAnimator ofArgb(@Nullable Object target, @NonNull String propertyName,
28 | int... values) {
29 | ObjectAnimator animator = ObjectAnimator.ofInt(target, propertyName, values);
30 | animator.setEvaluator(new ArgbEvaluator());
31 | return animator;
32 | }
33 |
34 | @NonNull
35 | public static ObjectAnimator ofArgb(@Nullable T target,
36 | @NonNull Property property, int... values) {
37 | ObjectAnimator animator = ObjectAnimator.ofInt(target, property, values);
38 | animator.setEvaluator(new ArgbEvaluator());
39 | return animator;
40 | }
41 |
42 | @NonNull
43 | public static ObjectAnimator ofFloat(@Nullable Object target, @NonNull String xPropertyName,
44 | @NonNull String yPropertyName, @NonNull Path path) {
45 |
46 | float[] xValues = new float[NUM_POINTS];
47 | float[] yValues = new float[NUM_POINTS];
48 | calculateXYValues(path, xValues, yValues);
49 |
50 | PropertyValuesHolder xPvh = PropertyValuesHolder.ofFloat(xPropertyName, xValues);
51 | PropertyValuesHolder yPvh = PropertyValuesHolder.ofFloat(yPropertyName, yValues);
52 |
53 | return ObjectAnimator.ofPropertyValuesHolder(target, xPvh, yPvh);
54 | }
55 |
56 | @NonNull
57 | public static ObjectAnimator ofFloat(@Nullable T target,
58 | @NonNull Property xProperty,
59 | @NonNull Property yProperty,
60 | @NonNull Path path) {
61 |
62 | float[] xValues = new float[NUM_POINTS];
63 | float[] yValues = new float[NUM_POINTS];
64 | calculateXYValues(path, xValues, yValues);
65 |
66 | PropertyValuesHolder xPvh = PropertyValuesHolder.ofFloat(xProperty, xValues);
67 | PropertyValuesHolder yPvh = PropertyValuesHolder.ofFloat(yProperty, yValues);
68 |
69 | return ObjectAnimator.ofPropertyValuesHolder(target, xPvh, yPvh);
70 | }
71 |
72 | @NonNull
73 | public static ObjectAnimator ofInt(@Nullable Object target, @NonNull String xPropertyName,
74 | @NonNull String yPropertyName, @NonNull Path path) {
75 |
76 | int[] xValues = new int[NUM_POINTS];
77 | int[] yValues = new int[NUM_POINTS];
78 | calculateXYValues(path, xValues, yValues);
79 |
80 | PropertyValuesHolder xPvh = PropertyValuesHolder.ofInt(xPropertyName, xValues);
81 | PropertyValuesHolder yPvh = PropertyValuesHolder.ofInt(yPropertyName, yValues);
82 |
83 | return ObjectAnimator.ofPropertyValuesHolder(target, xPvh, yPvh);
84 | }
85 |
86 | @NonNull
87 | public static ObjectAnimator ofInt(@Nullable T target,
88 | @NonNull Property xProperty,
89 | @NonNull Property yProperty,
90 | @NonNull Path path) {
91 |
92 | int[] xValues = new int[NUM_POINTS];
93 | int[] yValues = new int[NUM_POINTS];
94 | calculateXYValues(path, xValues, yValues);
95 |
96 | PropertyValuesHolder xPvh = PropertyValuesHolder.ofInt(xProperty, xValues);
97 | PropertyValuesHolder yPvh = PropertyValuesHolder.ofInt(yProperty, yValues);
98 |
99 | return ObjectAnimator.ofPropertyValuesHolder(target, xPvh, yPvh);
100 | }
101 |
102 | private static void calculateXYValues(@NonNull Path path,
103 | @NonNull @Size(NUM_POINTS) float[] xValues,
104 | @NonNull @Size(NUM_POINTS) float[] yValues) {
105 |
106 | PathMeasure pathMeasure = new PathMeasure(path, false /* forceClosed */);
107 | float pathLength = pathMeasure.getLength();
108 |
109 | float[] position = new float[2];
110 | for (int i = 0; i < NUM_POINTS; ++i) {
111 | float distance = (i * pathLength) / (NUM_POINTS - 1);
112 | pathMeasure.getPosTan(distance, position, null /* tangent */);
113 | xValues[i] = position[0];
114 | yValues[i] = position[1];
115 | }
116 | }
117 |
118 | private static void calculateXYValues(@NonNull Path path,
119 | @NonNull @Size(NUM_POINTS) int[] xValues,
120 | @NonNull @Size(NUM_POINTS) int[] yValues) {
121 |
122 | PathMeasure pathMeasure = new PathMeasure(path, false /* forceClosed */);
123 | float pathLength = pathMeasure.getLength();
124 |
125 | float[] position = new float[2];
126 | for (int i = 0; i < NUM_POINTS; ++i) {
127 | float distance = (i * pathLength) / (NUM_POINTS - 1);
128 | pathMeasure.getPosTan(distance, position, null /* tangent */);
129 | xValues[i] = Math.round(position[0]);
130 | yValues[i] = Math.round(position[1]);
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/library/src/main/java/me/zhanghai/android/materialprogressbar/internal/ObjectAnimatorCompatLollipop.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Zhang Hai
3 | * All Rights Reserved.
4 | */
5 |
6 | package me.zhanghai.android.materialprogressbar.internal;
7 |
8 | import android.animation.ObjectAnimator;
9 | import android.annotation.TargetApi;
10 | import android.graphics.Path;
11 | import android.os.Build;
12 | import android.util.Property;
13 |
14 | import androidx.annotation.NonNull;
15 | import androidx.annotation.Nullable;
16 |
17 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
18 | class ObjectAnimatorCompatLollipop {
19 |
20 | private ObjectAnimatorCompatLollipop() {}
21 |
22 | @NonNull
23 | public static ObjectAnimator ofArgb(@Nullable Object target, @NonNull String propertyName,
24 | int... values) {
25 | return ObjectAnimator.ofArgb(target, propertyName, values);
26 | }
27 |
28 | @NonNull
29 | public static ObjectAnimator ofArgb(@Nullable T target,
30 | @NonNull Property property, int... values) {
31 | return ObjectAnimator.ofArgb(target, property, values);
32 | }
33 |
34 | @NonNull
35 | public static ObjectAnimator ofFloat(@Nullable Object target, @NonNull String xPropertyName,
36 | @NonNull String yPropertyName, @NonNull Path path) {
37 | return ObjectAnimator.ofFloat(target, xPropertyName, yPropertyName, path);
38 | }
39 |
40 | @NonNull
41 | public static ObjectAnimator ofFloat(@Nullable T target,
42 | @NonNull Property xProperty,
43 | @NonNull Property yProperty,
44 | @NonNull Path path) {
45 | return ObjectAnimator.ofFloat(target, xProperty, yProperty, path);
46 | }
47 |
48 | @NonNull
49 | public static ObjectAnimator ofInt(@Nullable Object target, @NonNull String xPropertyName,
50 | @NonNull String yPropertyName, @NonNull Path path) {
51 | return ObjectAnimator.ofInt(target, xPropertyName, yPropertyName, path);
52 | }
53 |
54 | @NonNull
55 | public static ObjectAnimator ofInt(@Nullable T target,
56 | @NonNull Property xProperty,
57 | @NonNull Property yProperty,
58 | @NonNull Path path) {
59 | return ObjectAnimator.ofInt(target, xProperty, yProperty, path);
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/library/src/main/java/me/zhanghai/android/materialprogressbar/internal/ThemeUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Zhang Hai
3 | * All Rights Reserved.
4 | */
5 |
6 | package me.zhanghai.android.materialprogressbar.internal;
7 |
8 | import android.content.Context;
9 | import android.content.res.TypedArray;
10 |
11 | import androidx.annotation.AttrRes;
12 | import androidx.annotation.ColorInt;
13 | import androidx.annotation.NonNull;
14 |
15 | public class ThemeUtils {
16 |
17 | private ThemeUtils() {}
18 |
19 | @ColorInt
20 | public static int getColorFromAttrRes(@AttrRes int attrRes, @ColorInt int defaultValue,
21 | @NonNull Context context) {
22 | TypedArray a = context.obtainStyledAttributes(new int[] { attrRes });
23 | try {
24 | return a.getColor(0, defaultValue);
25 | } finally {
26 | a.recycle();
27 | }
28 | }
29 |
30 | public static float getFloatFromAttrRes(@AttrRes int attrRes, float defaultValue,
31 | @NonNull Context context) {
32 | TypedArray a = context.obtainStyledAttributes(new int[] { attrRes });
33 | try {
34 | return a.getFloat(0, defaultValue);
35 | } finally {
36 | a.recycle();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/library/src/main/java/me/zhanghai/android/materialprogressbar/internal/ValueAnimatorCompat.java:
--------------------------------------------------------------------------------
1 | package me.zhanghai.android.materialprogressbar.internal;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.annotation.SuppressLint;
5 | import android.os.Build;
6 |
7 | import java.lang.reflect.Field;
8 | import java.lang.reflect.Method;
9 |
10 | import androidx.annotation.NonNull;
11 | import androidx.annotation.Nullable;
12 |
13 | public class ValueAnimatorCompat {
14 |
15 | @NonNull
16 | private static final Object sValueAnimatorGetDurationScaleMethodLock = new Object();
17 | private static boolean sValueAnimatorGetDurationScaleMethodInitialized;
18 | @Nullable
19 | private static Method sValueAnimatorGetDurationScaleMethod;
20 |
21 | @NonNull
22 | private static final Object sValueAnimatorSDurationScaleFieldLock = new Object();
23 | private static boolean sValueAnimatorSDurationScaleFieldInitialized;
24 | @Nullable
25 | private static Field sValueAnimatorSDurationScaleField;
26 |
27 |
28 | private ValueAnimatorCompat() {}
29 |
30 | public static boolean areAnimatorsEnabled() {
31 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
32 | return ValueAnimator.areAnimatorsEnabled();
33 | }
34 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
35 | Method valueAnimatorGetDurationScaleMethod = getValueAnimatorGetDurationScaleMethod();
36 | if (valueAnimatorGetDurationScaleMethod != null) {
37 | try {
38 | float durationScale = (float) valueAnimatorGetDurationScaleMethod.invoke(null);
39 | return durationScale != 0;
40 | } catch (Exception e) {
41 | e.printStackTrace();
42 | }
43 | }
44 | }
45 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
46 | Field valueAnimatorSDurationScaleField = getValueAnimatorSDurationScaleField();
47 | if (valueAnimatorSDurationScaleField != null) {
48 | try {
49 | float durationScale = (float) valueAnimatorSDurationScaleField.get(null);
50 | return durationScale != 0;
51 | } catch (Exception e) {
52 | e.printStackTrace();
53 | }
54 | }
55 | }
56 | return true;
57 | }
58 |
59 | @Nullable
60 | @SuppressLint("PrivateApi")
61 | private static Method getValueAnimatorGetDurationScaleMethod() {
62 | synchronized (sValueAnimatorGetDurationScaleMethodLock) {
63 | if (!sValueAnimatorGetDurationScaleMethodInitialized) {
64 | try {
65 | //noinspection JavaReflectionMemberAccess
66 | sValueAnimatorGetDurationScaleMethod = ValueAnimator.class.getDeclaredMethod(
67 | "getDurationScale");
68 | sValueAnimatorGetDurationScaleMethod.setAccessible(true);
69 | } catch (Exception e) {
70 | e.printStackTrace();
71 | }
72 | sValueAnimatorGetDurationScaleMethodInitialized = true;
73 | }
74 | return sValueAnimatorGetDurationScaleMethod;
75 | }
76 | }
77 |
78 | @Nullable
79 | private static Field getValueAnimatorSDurationScaleField() {
80 | synchronized (sValueAnimatorSDurationScaleFieldLock) {
81 | if (!sValueAnimatorSDurationScaleFieldInitialized) {
82 | try {
83 | //noinspection JavaReflectionMemberAccess
84 | sValueAnimatorSDurationScaleField = ValueAnimator.class.getDeclaredField(
85 | "sDurationScale");
86 | sValueAnimatorSDurationScaleField.setAccessible(true);
87 | } catch (Exception e) {
88 | e.printStackTrace();
89 | }
90 | sValueAnimatorSDurationScaleFieldInitialized = true;
91 | }
92 | return sValueAnimatorSDurationScaleField;
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/library/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
31 |
32 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/library/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
20 |
21 |
25 |
26 |
35 |
36 |
42 |
43 |
49 |
50 |
56 |
57 |
63 |
64 |
70 |
71 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 |
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 |
5 | compileSdkVersion Integer.parseInt(project.ANDROID_COMPILE_SDK_VERSION)
6 | buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
7 |
8 | defaultConfig {
9 | applicationId "me.zhanghai.android.materialprogressbar.sample"
10 | minSdkVersion Integer.parseInt(project.ANDROID_MIN_SDK_VERSION)
11 | targetSdkVersion Integer.parseInt(project.ANDROID_TARGET_SDK_VERSION)
12 | versionCode Integer.parseInt(project.VERSION_CODE)
13 | versionName project.VERSION_NAME
14 | }
15 |
16 | signingConfigs {
17 | release {
18 | storeFile file('../../github.jks')
19 | storePassword System.console() != null ? System.console().readLine("\nKeystore password: ") : ""
20 | keyAlias 'materialprogressbar'
21 | keyPassword System.console() != null ? System.console().readLine("\nKey password: ") : ""
22 | }
23 | }
24 |
25 | buildTypes {
26 | release {
27 | minifyEnabled true
28 | shrinkResources true
29 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
30 | signingConfig signingConfigs.release
31 | }
32 | }
33 | }
34 |
35 | dependencies {
36 | implementation fileTree(dir: 'libs', include: ['*.jar'])
37 | implementation 'androidx.appcompat:appcompat:1.0.2'
38 | implementation 'com.jakewharton:butterknife:9.0.0-rc1'
39 | annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0-rc1'
40 | implementation project(':library')
41 | }
42 |
--------------------------------------------------------------------------------
/sample/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /opt/android-sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
11 |
12 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
34 |
37 |
38 |
39 |
43 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/sample/src/main/java/me/zhanghai/android/materialprogressbar/sample/AboutActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Zhang Hai
3 | * All Rights Reserved.
4 | */
5 |
6 | package me.zhanghai.android.materialprogressbar.sample;
7 |
8 | import android.os.Bundle;
9 | import android.text.method.LinkMovementMethod;
10 | import android.view.MenuItem;
11 | import android.widget.TextView;
12 |
13 | import androidx.appcompat.app.AppCompatActivity;
14 | import butterknife.BindView;
15 | import butterknife.ButterKnife;
16 |
17 | public class AboutActivity extends AppCompatActivity {
18 |
19 | @BindView(R.id.version)
20 | TextView mVersionText;
21 | @BindView(R.id.github)
22 | TextView mGithubText;
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 |
28 | setContentView(R.layout.about_activity);
29 | ButterKnife.bind(this);
30 |
31 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
32 |
33 | String version = getString(R.string.about_version_format, BuildConfig.VERSION_NAME);
34 | mVersionText.setText(version);
35 | mGithubText.setMovementMethod(LinkMovementMethod.getInstance());
36 | }
37 |
38 | @Override
39 | public boolean onOptionsItemSelected(MenuItem item) {
40 | switch (item.getItemId()) {
41 | case android.R.id.home:
42 | AppUtils.navigateUp(this);
43 | return true;
44 | default:
45 | return super.onOptionsItemSelected(item);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/sample/src/main/java/me/zhanghai/android/materialprogressbar/sample/Animators.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Zhang Hai
3 | * All Rights Reserved.
4 | */
5 |
6 | package me.zhanghai.android.materialprogressbar.sample;
7 |
8 | import android.animation.ValueAnimator;
9 | import android.view.animation.LinearInterpolator;
10 | import android.widget.ProgressBar;
11 |
12 | class Animators {
13 |
14 | private Animators() {}
15 |
16 | public static ValueAnimator makeDeterminateCircularPrimaryProgressAnimator(
17 | final ProgressBar[] progressBars) {
18 | ValueAnimator animator = ValueAnimator.ofInt(0, 150);
19 | animator.setDuration(6000);
20 | animator.setInterpolator(new LinearInterpolator());
21 | animator.setRepeatCount(ValueAnimator.INFINITE);
22 | animator.addUpdateListener(
23 | new ValueAnimator.AnimatorUpdateListener() {
24 | @Override
25 | public void onAnimationUpdate(ValueAnimator animator) {
26 | int value = (int) animator.getAnimatedValue();
27 | for (ProgressBar progressBar : progressBars) {
28 | progressBar.setProgress(value);
29 | }
30 | }
31 | });
32 | return animator;
33 | }
34 |
35 | public static ValueAnimator makeDeterminateCircularPrimaryAndSecondaryProgressAnimator(
36 | final ProgressBar[] progressBars) {
37 | ValueAnimator animator = makeDeterminateCircularPrimaryProgressAnimator(progressBars);
38 | animator.addUpdateListener(
39 | new ValueAnimator.AnimatorUpdateListener() {
40 | @Override
41 | public void onAnimationUpdate(ValueAnimator animator) {
42 | int value = Math.round(1.25f * (int) animator.getAnimatedValue());
43 | for (ProgressBar progressBar : progressBars) {
44 | progressBar.setSecondaryProgress(value);
45 | }
46 | }
47 | });
48 | return animator;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/sample/src/main/java/me/zhanghai/android/materialprogressbar/sample/AppUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Zhang Hai
3 | * All Rights Reserved.
4 | */
5 |
6 | package me.zhanghai.android.materialprogressbar.sample;
7 |
8 | import android.app.Activity;
9 | import android.content.Intent;
10 | import android.os.Bundle;
11 |
12 | import androidx.core.app.NavUtils;
13 | import androidx.core.app.TaskStackBuilder;
14 |
15 | public class AppUtils {
16 |
17 | private AppUtils() {}
18 |
19 | // From http://developer.android.com/training/implementing-navigation/ancestral.html#NavigateUp .
20 | public static void navigateUp(Activity activity, Bundle extras) {
21 | Intent upIntent = NavUtils.getParentActivityIntent(activity);
22 | if (upIntent != null) {
23 | if (extras != null) {
24 | upIntent.putExtras(extras);
25 | }
26 | if (NavUtils.shouldUpRecreateTask(activity, upIntent)) {
27 | // This activity is NOT part of this app's task, so create a new task
28 | // when navigating up, with a synthesized back stack.
29 | TaskStackBuilder.create(activity)
30 | // Add all of this activity's parents to the back stack.
31 | .addNextIntentWithParentStack(upIntent)
32 | // Navigate up to the closest parent.
33 | .startActivities();
34 | } else {
35 | // This activity is part of this app's task, so simply
36 | // navigate up to the logical parent activity.
37 | // According to http://stackoverflow.com/a/14792752/2420519
38 | //NavUtils.navigateUpTo(activity, upIntent);
39 | upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
40 | activity.startActivity(upIntent);
41 | }
42 | }
43 | activity.finish();
44 | }
45 |
46 | public static void navigateUp(Activity activity) {
47 | navigateUp(activity, null);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/sample/src/main/java/me/zhanghai/android/materialprogressbar/sample/DeterminateCircularSampleActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Zhang Hai
3 | * All Rights Reserved.
4 | */
5 |
6 | package me.zhanghai.android.materialprogressbar.sample;
7 |
8 | import android.animation.ValueAnimator;
9 | import android.os.Bundle;
10 | import android.view.MenuItem;
11 | import android.widget.ProgressBar;
12 |
13 | import androidx.appcompat.app.AppCompatActivity;
14 | import butterknife.BindViews;
15 | import butterknife.ButterKnife;
16 |
17 | public class DeterminateCircularSampleActivity extends AppCompatActivity {
18 |
19 | @BindViews({
20 | R.id.normal_progress,
21 | R.id.tinted_normal_progress,
22 | R.id.dynamic_progress,
23 | R.id.tinted_dynamic_progress
24 | })
25 | ProgressBar[] mPrimaryProgressBars;
26 | @BindViews({
27 | R.id.normal_secondary_progress,
28 | R.id.normal_background_progress,
29 | R.id.tinted_normal_secondary_progress,
30 | R.id.tinted_normal_background_progress,
31 | R.id.dynamic_secondary_progress,
32 | R.id.dynamic_background_progress,
33 | R.id.tinted_dynamic_secondary_progress,
34 | R.id.tinted_dynamic_background_progress
35 | })
36 | ProgressBar[] mPrimaryAndSecondaryProgressBars;
37 |
38 | private ValueAnimator mPrimaryProgressAnimator;
39 | private ValueAnimator mPrimaryAndSecondaryProgressAnimator;
40 |
41 | @Override
42 | protected void onCreate(Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 |
45 | setContentView(R.layout.determinate_circular_sample_activity);
46 | ButterKnife.bind(this);
47 |
48 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
49 |
50 | mPrimaryProgressAnimator =
51 | Animators.makeDeterminateCircularPrimaryProgressAnimator(mPrimaryProgressBars);
52 | mPrimaryAndSecondaryProgressAnimator =
53 | Animators.makeDeterminateCircularPrimaryAndSecondaryProgressAnimator(
54 | mPrimaryAndSecondaryProgressBars);
55 | }
56 |
57 | @Override
58 | public void onAttachedToWindow() {
59 | super.onAttachedToWindow();
60 |
61 | mPrimaryProgressAnimator.start();
62 | mPrimaryAndSecondaryProgressAnimator.start();
63 | }
64 |
65 | @Override
66 | public void onDetachedFromWindow() {
67 | super.onDetachedFromWindow();
68 |
69 | mPrimaryProgressAnimator.end();
70 | mPrimaryAndSecondaryProgressAnimator.end();
71 | }
72 |
73 | @Override
74 | public boolean onOptionsItemSelected(MenuItem item) {
75 | switch (item.getItemId()) {
76 | case android.R.id.home:
77 | AppUtils.navigateUp(this);
78 | return true;
79 | default:
80 | return super.onOptionsItemSelected(item);
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/sample/src/main/java/me/zhanghai/android/materialprogressbar/sample/MainActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Zhang Hai
3 | * All Rights Reserved.
4 | */
5 |
6 | package me.zhanghai.android.materialprogressbar.sample;
7 |
8 | import android.animation.ValueAnimator;
9 | import android.content.Intent;
10 | import android.os.Bundle;
11 | import android.view.Menu;
12 | import android.view.MenuItem;
13 | import android.widget.ProgressBar;
14 |
15 | import androidx.appcompat.app.AppCompatActivity;
16 | import butterknife.BindViews;
17 | import butterknife.ButterKnife;
18 |
19 | public class MainActivity extends AppCompatActivity {
20 |
21 | @BindViews({
22 | R.id.determinate_circular_large_progress,
23 | R.id.determinate_circular_progress,
24 | R.id.determinate_circular_small_progress
25 | })
26 | ProgressBar[] mDeterminateCircularProgressBars;
27 |
28 | private ValueAnimator mDeterminateCircularProgressAnimator;
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 |
34 | setContentView(R.layout.main_activity);
35 | ButterKnife.bind(this);
36 |
37 | mDeterminateCircularProgressAnimator =
38 | Animators.makeDeterminateCircularPrimaryProgressAnimator(
39 | mDeterminateCircularProgressBars);
40 | }
41 |
42 | @Override
43 | public void onAttachedToWindow() {
44 | super.onAttachedToWindow();
45 |
46 | mDeterminateCircularProgressAnimator.start();
47 | }
48 |
49 | @Override
50 | public void onDetachedFromWindow() {
51 | super.onDetachedFromWindow();
52 |
53 | mDeterminateCircularProgressAnimator.end();
54 | }
55 |
56 | @Override
57 | public boolean onCreateOptionsMenu(Menu menu) {
58 | getMenuInflater().inflate(R.menu.menu_main, menu);
59 | return true;
60 | }
61 |
62 | @Override
63 | public boolean onOptionsItemSelected(MenuItem item) {
64 | switch (item.getItemId()) {
65 | case R.id.action_about:
66 | startActivity(new Intent(this, AboutActivity.class));
67 | return true;
68 | case R.id.action_determinate_circular_sample:
69 | startActivity(new Intent(this, DeterminateCircularSampleActivity.class));
70 | return true;
71 | default:
72 | return super.onOptionsItemSelected(item);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/sample/src/main/launcher_icon-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/sample/src/main/launcher_icon-web.png
--------------------------------------------------------------------------------
/sample/src/main/res/layout/about_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
15 |
16 |
25 |
26 |
31 |
32 |
39 |
40 |
47 |
48 |
55 |
56 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/determinate_circular_sample_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
15 |
16 |
24 |
25 |
31 |
32 |
35 |
36 |
43 |
44 |
51 |
52 |
60 |
61 |
62 |
69 |
70 |
73 |
74 |
82 |
83 |
92 |
93 |
104 |
105 |
106 |
113 |
114 |
117 |
118 |
126 |
127 |
135 |
136 |
145 |
146 |
147 |
154 |
155 |
158 |
159 |
168 |
169 |
179 |
180 |
192 |
193 |
194 |
195 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/main_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
15 |
16 |
24 |
25 |
26 |
27 |
32 |
33 |
38 |
39 |
45 |
46 |
51 |
52 |
59 |
60 |
65 |
66 |
76 |
77 |
78 |
79 |
84 |
85 |
90 |
91 |
96 |
97 |
102 |
103 |
109 |
110 |
115 |
116 |
123 |
124 |
125 |
126 |
131 |
132 |
137 |
138 |
143 |
144 |
149 |
150 |
153 |
154 |
161 |
162 |
169 |
170 |
177 |
178 |
179 |
180 |
181 |
186 |
187 |
192 |
193 |
196 |
197 |
203 |
204 |
210 |
211 |
217 |
218 |
219 |
224 |
225 |
228 |
229 |
235 |
236 |
242 |
243 |
249 |
250 |
251 |
252 |
253 |
258 |
259 |
266 |
267 |
273 |
274 |
280 |
281 |
282 |
292 |
293 |
294 |
301 |
302 |
308 |
309 |
315 |
316 |
317 |
326 |
327 |
328 |
329 |
--------------------------------------------------------------------------------
/sample/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
26 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/launcher_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/sample/src/main/res/mipmap-hdpi/launcher_icon.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/launcher_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/sample/src/main/res/mipmap-mdpi/launcher_icon.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/launcher_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/sample/src/main/res/mipmap-xhdpi/launcher_icon.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/launcher_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/sample/src/main/res/mipmap-xxhdpi/launcher_icon.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxxhdpi/launcher_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/sample/src/main/res/mipmap-xxxhdpi/launcher_icon.png
--------------------------------------------------------------------------------
/sample/src/main/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 | 24dp
10 |
11 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 | #f44336
10 | #42f44336
11 |
12 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 | 16dp
10 | 16dp
11 |
12 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 | MaterialProgressBar Sample
11 |
12 | Framework Implementation
13 | Library Implementation
14 | Library Implementation (Tinted)
15 | Determinate Horizontal ProgressBar
16 | Indeterminate Horizontal ProgressBar
17 | Determinate Circular ProgressBar
18 | Indeterminate Circular ProgressBar
19 | ProgressBar on Toolbar
20 | Horizontal
21 | Indeterminate Horizontal
22 | (Not Available)
23 |
24 | About
25 | @string/determinate_circular_title
26 |
27 | Determinate Circular Sample
28 | Normal Style
29 | Normal Style (Tinted)
30 | Dynamic Style
31 | Dynamic Style (Tinted)
32 |
33 | About
34 | MaterialProgressBar
35 | Version %1$s
36 | Zhang Hai 2015–2016
37 | View on GitHub
38 |
39 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/screenshot/android_4_4_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/screenshot/android_4_4_4.png
--------------------------------------------------------------------------------
/screenshot/android_4_4_4_raw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/screenshot/android_4_4_4_raw.png
--------------------------------------------------------------------------------
/screenshot/android_5_0_1_samsung.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/screenshot/android_5_0_1_samsung.png
--------------------------------------------------------------------------------
/screenshot/android_5_0_1_samsung_raw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/screenshot/android_5_0_1_samsung_raw.png
--------------------------------------------------------------------------------
/screenshot/android_5_1_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/screenshot/android_5_1_1.png
--------------------------------------------------------------------------------
/screenshot/android_5_1_1_raw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/screenshot/android_5_1_1_raw.png
--------------------------------------------------------------------------------
/screenshot/android_6_0_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/screenshot/android_6_0_1.png
--------------------------------------------------------------------------------
/screenshot/android_6_0_1_raw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhanghai/MaterialProgressBar/2b39099237bb265b6a20357470e6cecf6e3112b2/screenshot/android_6_0_1_raw.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':library', ':sample'
2 |
--------------------------------------------------------------------------------