diff --git a/README.md b/README.md index 4e1169e..07578e6 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,17 @@ ProgressProfileView Android custom view to load an avatar or profile image with a progress indicator. -It works on Marshmallow. +It also works on Marshmallow. ![Portrait][1] +You can customize the Component as you wish. + +![Ring Samples][2] + **You can also Preview the result on Android Studio!** -![Android Studio Preview][2] +![Android Studio Preview][3] Background ---------- @@ -28,7 +32,7 @@ How to: If you are working with gradle, add the dependency to your build.gradle file: ```groovy dependencies{ - compile 'com.kuassivi.view:progressprofile:1.0.4' + compile 'com.kuassivi.view:progressprofile:1.0.5' } ``` If you are working with maven, do it into your pom.xml @@ -36,7 +40,7 @@ If you are working with maven, do it into your pom.xml com.kuassivi.view progressprofile - 1.0.4 + 1.0.5 aar ``` @@ -54,7 +58,8 @@ Add the **ProgressProfileView** component in some place on the layout. android:src="@drawable/my_avatar" app:progress="42" app:progressRingSize="10dp" - app:progressRingCap="ROUND"/> + app:progressRingCap="ROUND" + app:progressRingOutline="true"/> ``` >Get the object on your activity or fragment. @@ -88,16 +93,17 @@ profile.getAnimator().addUpdateListener(new AnimatorUpdateListener()); profile.getAnimator().setInterpolator(new AccelerateDecelerateInterpolator()); ``` ->If you are loading images from Glide, consider to implement a custom ViewTarget like this one +>If you are loading images with Glide or Picasso, do it as usual ```java // Using Glide as usual Glide.with(this) .load("http://your/server/path") .placeholder(R.drawable.ic_icon_user_default) - .fitCenter() // Fit and center the bitmap .into(profile); ``` +> Be careful when using `fitCenter()` method of Glide, or any other similar kind of method, because it will scale the bitmap, and the Progress Profile component will loose its original bounds! + Features: --------- @@ -108,6 +114,7 @@ Features: * `app:backgroundRingColor="@color/my_color"` - Set the color of the background ring (it can be an hex color as well) * `app:progressRingColor="@color/my_color"` - Set the color of the progress ring (it can be an hex color as well) * `app:progressRingCap="BUTT"` - Set the cap style of the progress ring (Possible values: BUTT, ROUND, SQUARE) + * `app:progressRingOutline="true"` - Set the ring as an Outline based on the padding of the ImageView, by default is `false`. License ------- @@ -127,4 +134,5 @@ See the License for the specific language governing permissions and limitations under the License. [1]: ./art/portrait.gif -[2]: ./art/android-studio-preview.png +[2]: ./art/ring-samples.png +[3]: ./art/android-studio-preview.png diff --git a/art/portrait.gif b/art/portrait.gif index 4df9554..fe82779 100644 Binary files a/art/portrait.gif and b/art/portrait.gif differ diff --git a/art/ring-samples.png b/art/ring-samples.png new file mode 100644 index 0000000..5cef043 Binary files /dev/null and b/art/ring-samples.png differ diff --git a/example/build.gradle b/example/build.gradle index 90c7351..271c51e 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.kuassivi.progressprofile" minSdkVersion 16 targetSdkVersion 23 - versionCode 1 - versionName "1.0" + versionCode 2 + versionName "1.1" } buildTypes { release { @@ -21,7 +21,7 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:23.0.1' + compile 'com.android.support:appcompat-v7:23.1.0' compile 'com.github.bumptech.glide:glide:3.6.1' compile project(':progressprofile') } diff --git a/example/example.iml b/example/example.iml index b6a6568..7368019 100644 --- a/example/example.iml +++ b/example/example.iml @@ -88,10 +88,10 @@ - - - + + + \ No newline at end of file diff --git a/example/src/main/java/com/kuassivi/progressprofile/MainActivity.java b/example/src/main/java/com/kuassivi/progressprofile/MainActivity.java index 7b23a1e..113b10b 100644 --- a/example/src/main/java/com/kuassivi/progressprofile/MainActivity.java +++ b/example/src/main/java/com/kuassivi/progressprofile/MainActivity.java @@ -2,6 +2,7 @@ import android.animation.ValueAnimator; import android.os.Bundle; +import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; @@ -20,27 +21,33 @@ protected void onCreate(Bundle savedInstanceState) { final TextView percentage = (TextView) findViewById(R.id.percentage); - ProgressProfileView profile = (ProgressProfileView) findViewById(R.id.profile); + final ProgressProfileView profile = (ProgressProfileView) findViewById(R.id.profile); profile.getAnimator().setInterpolator(new AccelerateDecelerateInterpolator()); - profile.setProgress(38.5f); + profile.setProgress(0); - // Using Glide as usual - Glide.with(this) - .load("http://lorempixel.com/500/500/people/1") - .placeholder(R.drawable.ic_icon_user_default) - .fitCenter() // Fit and center the bitmap - .into(profile); - - // Show the current percentage animated - profile.getAnimator().addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + new Handler().postDelayed(new Runnable() { @Override - public void onAnimationUpdate(ValueAnimator animation) { - int absValue = Float.valueOf(animation.getAnimatedValue().toString()).intValue(); - percentage.setText("Completed: " + absValue + "%"); - } - }); + public void run() { + profile.setProgress(38.5f); + // Using Glide as usual + Glide.with(MainActivity.this) + .load("http://lorempixel.com/500/500/people/1") + .placeholder(R.drawable.ic_icon_user_default) + .fitCenter() // Fit and center the bitmap + .into(profile); - profile.startAnimation(); + // Show the current percentage animated + profile.getAnimator().addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + int absValue = Float.valueOf(animation.getAnimatedValue().toString()).intValue(); + percentage.setText("Completed: " + absValue + "%"); + } + }); + + profile.startAnimation(); + } + }, 2000); } @Override diff --git a/example/src/main/res/layout/activity_main.xml b/example/src/main/res/layout/activity_main.xml index 2e6ff30..fdb3b3b 100644 --- a/example/src/main/res/layout/activity_main.xml +++ b/example/src/main/res/layout/activity_main.xml @@ -17,10 +17,11 @@ android:adjustViewBounds="true" android:layout_centerInParent="true" android:layout_margin="50dp" - tools:src="@drawable/ic_icon_user_default" + android:src="@drawable/ic_icon_user_default" app:progress="42" app:progressRingSize="10dp" - app:progressRingCap="ROUND"/> + app:progressRingCap="ROUND" + app:progressRingOutline="true"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/progressprofile/progressprofile.iml b/progressprofile/progressprofile.iml index 9d5ca47..85f45ec 100644 --- a/progressprofile/progressprofile.iml +++ b/progressprofile/progressprofile.iml @@ -94,8 +94,8 @@ - - + + \ No newline at end of file diff --git a/progressprofile/src/main/java/com/kuassivi/view/ProgressProfileView.java b/progressprofile/src/main/java/com/kuassivi/view/ProgressProfileView.java index 0e277b7..32599c0 100644 --- a/progressprofile/src/main/java/com/kuassivi/view/ProgressProfileView.java +++ b/progressprofile/src/main/java/com/kuassivi/view/ProgressProfileView.java @@ -17,6 +17,7 @@ import android.animation.ObjectAnimator; import android.animation.ValueAnimator; +import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; @@ -25,7 +26,9 @@ import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Shader; +import android.os.Build; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.animation.Interpolator; import android.view.animation.OvershootInterpolator; @@ -76,6 +79,7 @@ public class ProgressProfileView extends ImageView { */ private float mBackgroundRingSize = 40; private float mProgressRingSize = mBackgroundRingSize; + private boolean mProgressRingOutline = false; /** * Default progress colors @@ -122,7 +126,7 @@ public class ProgressProfileView extends ImageView { * Bounds of the ring */ private RectF mRingBounds; - private float mOffsetProgressRingSize; + private float mOffsetRingSize; /* * Masks for clipping the current drawable in a circle @@ -135,26 +139,34 @@ public ProgressProfileView(Context context) { super(context); } - public ProgressProfileView(Context context, AttributeSet attrs) { + public ProgressProfileView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); - init(attrs, 0); + init(attrs, 0, 0); } - public ProgressProfileView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(attrs, defStyle); + public ProgressProfileView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(attrs, defStyleAttr, 0); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public ProgressProfileView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(attrs, defStyleAttr, defStyleRes); } /** * Parse attributes * * @param attrs AttributeSet - * @param defStyle int + * @param defStyleAttr int + * @param defStyleRes int */ - private void init(AttributeSet attrs, int defStyle) { + private void init(@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { // Load attributes final TypedArray a = getContext().obtainStyledAttributes( - attrs, R.styleable.ProgressProfileView, defStyle, 0); + attrs, R.styleable.ProgressProfileView, defStyleAttr, defStyleRes); setMax(a.getFloat( R.styleable.ProgressProfileView_max, mMax)); @@ -164,12 +176,16 @@ private void init(AttributeSet attrs, int defStyle) { if (a.hasValue(R.styleable.ProgressProfileView_progressRingSize)) { setProgressRingSize(a.getDimension( R.styleable.ProgressProfileView_progressRingSize, mProgressRingSize)); - setBackgroundRingSize(getProgressRingSize()); + setBackgroundRingSize(mProgressRingSize); } } else { setBackgroundRingSize(a.getDimension( R.styleable.ProgressProfileView_backgroundRingSize, mBackgroundRingSize)); + setProgressRingSize(a.getDimension( + R.styleable.ProgressProfileView_progressRingSize, mProgressRingSize)); } + setProgressRingOutline( + a.getBoolean(R.styleable.ProgressProfileView_progressRingOutline, false)); setBackgroundRingColor(a.getColor( R.styleable.ProgressProfileView_backgroundRingColor, mBackgroundRingColor)); setProgressRingColor(a.getColor( @@ -230,6 +246,15 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) { mViewWidth = w; mViewHeight = h; + // Apply ring as outline + if(isProgressRingOutline()) { + setPadding( + Float.valueOf(mBackgroundRingSize + getPaddingLeft()).intValue(), + Float.valueOf(mBackgroundRingSize + getPaddingTop()).intValue(), + Float.valueOf(mBackgroundRingSize + getPaddingRight()).intValue(), + Float.valueOf(mBackgroundRingSize + getPaddingBottom()).intValue()); + } + setupBounds(); setupBackgroundRingPaint(); setupProgressRingPaint(); @@ -249,24 +274,35 @@ private void setupBounds() { int xOffset = mViewWidth - minValue; int yOffset = mViewHeight - minValue; + + // Apply ring as outline + int outline = 0; + if(isProgressRingOutline()) { + outline = Float.valueOf(-mBackgroundRingSize).intValue(); + } + // Save padding plus offset - mPaddingTop = this.getPaddingTop() + (yOffset / 2); - mPaddingBottom = this.getPaddingBottom() + (yOffset / 2); - mPaddingLeft = this.getPaddingLeft() + (xOffset / 2); - mPaddingRight = this.getPaddingRight() + (xOffset / 2); + mPaddingTop = outline + this.getPaddingTop() + (yOffset / 2); + mPaddingBottom = outline + this.getPaddingBottom() + (yOffset / 2); + mPaddingLeft = outline + this.getPaddingLeft() + (xOffset / 2); + mPaddingRight = outline + this.getPaddingRight() + (xOffset / 2); + + // Bigger ring size + float biggerRingSize = mBackgroundRingSize > mProgressRingSize + ? mBackgroundRingSize : mProgressRingSize; // Save the half of the progress ring - mOffsetProgressRingSize = mProgressRingSize / 2; + mOffsetRingSize = biggerRingSize / 2; int width = getWidth(); int height = getHeight(); // Create the ring bounds Rect mRingBounds = new RectF( - mPaddingLeft + mOffsetProgressRingSize, - mPaddingTop + mOffsetProgressRingSize, - width - mPaddingRight - mOffsetProgressRingSize, - height - mPaddingBottom - mOffsetProgressRingSize); + mPaddingLeft + mOffsetRingSize, + mPaddingTop + mOffsetRingSize, + width - mPaddingRight - mOffsetRingSize, + height - mPaddingBottom - mOffsetRingSize); } private void setupMask() { @@ -344,10 +380,10 @@ protected void onDraw(@NonNull Canvas canvas) { // Crop ImageView resource to a circle canvas.drawCircle( - mRingBounds.centerX(), - mRingBounds.centerY(), - (mRingBounds.width() / 2) - mOffsetProgressRingSize, - mMaskPaint); + mRingBounds.centerX(), + mRingBounds.centerY(), + (mRingBounds.width() / 2) - (mBackgroundRingSize / 2), + mMaskPaint); // Draw the background ring if (mBackgroundRingSize > 0){ @@ -415,6 +451,22 @@ public void setProgressRingSize(float progressRingSize) { mProgressRingSize = progressRingSize; } + public float getBackgroundRingSize() { + return mBackgroundRingSize; + } + + public void setBackgroundRingSize(float backgroundRingSize) { + mBackgroundRingSize = backgroundRingSize; + } + + public boolean isProgressRingOutline() { + return mProgressRingOutline; + } + + public void setProgressRingOutline(boolean progressRingOutline) { + mProgressRingOutline = progressRingOutline; + } + public int getBackgroundRingColor() { return mBackgroundRingColor; } @@ -439,14 +491,6 @@ public void setProgressRingCap(int progressRingCap) { mProgressRingCap = getCap(progressRingCap); } - public float getBackgroundRingSize() { - return mBackgroundRingSize; - } - - public void setBackgroundRingSize(float backgroundRingSize) { - mBackgroundRingSize = backgroundRingSize; - } - private Paint.Cap getCap(int id) { for (Paint.Cap value : Paint.Cap.values()) { if (id == value.ordinal()) { diff --git a/progressprofile/src/main/res/values/attrs.xml b/progressprofile/src/main/res/values/attrs.xml index b5a8ab8..ca0a753 100644 --- a/progressprofile/src/main/res/values/attrs.xml +++ b/progressprofile/src/main/res/values/attrs.xml @@ -6,6 +6,7 @@ +