Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added animation duration feature. #74

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Advance
android:visibility="visible" //visible or gone
app:indicatorName="BallPulseIndicator"//Indicator Name
app:indicatorColor="your color"
app:animationDuration="desired duration" // Animation duration in milliseconds. Use this to control animation speed.
/>
```

Expand Down
41 changes: 41 additions & 0 deletions app/src/main/java/com/wang/avi/sample/IndicatorActivity.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.wang.avi.sample;

import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.InputFilter;
import android.text.InputType;
import android.util.TypedValue;
import android.view.View;
import android.widget.EditText;

import com.wang.avi.AVLoadingIndicatorView;

Expand All @@ -21,8 +27,11 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
setContentView(R.layout.activity_indicator);

String indicator=getIntent().getStringExtra("indicator");
int duration = getIntent().getIntExtra("duration", 0);
avi= (AVLoadingIndicatorView) findViewById(R.id.avi);
avi.setAnimationDuration(duration);
avi.setIndicator(indicator);
setUpDialog();
}

public void hideClick(View view) {
Expand All @@ -34,4 +43,36 @@ public void showClick(View view) {
avi.show();
// or avi.smoothToShow();
}

public void durationClick(View view) {
dialog.show();
}

private EditText editText;
private AlertDialog dialog;
private void setUpDialog(){
editText = new EditText(this);
editText.setInputType(InputType.TYPE_CLASS_NUMBER);
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(5)});
int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20,
getResources().getDisplayMetrics());
dialog = new AlertDialog.Builder(this)
.setTitle("Animation duration")
.setMessage("Enter desired animation duration in milliseconds.")
.setView(editText, padding, padding, padding, padding)
.setPositiveButton("APPLY", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String duration = editText.getText().toString().trim();
if (!duration.isEmpty()) {
setIntent(getIntent().putExtra("duration", Integer.parseInt(duration)));
recreate();
}
}
})
.setNegativeButton("CANCEL", null)
.create();

}

}
7 changes: 5 additions & 2 deletions app/src/main/java/com/wang/avi/sample/MyCustomIndicator.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public ArrayList<ValueAnimator> onCreateAnimators() {

ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.3f,1);

scaleAnim.setDuration(750);
scaleAnim.setDuration(getDuration());
scaleAnim.setRepeatCount(-1);
scaleAnim.setStartDelay(delays[i]);

Expand All @@ -68,5 +68,8 @@ public void onAnimationUpdate(ValueAnimator animation) {
return animators;
}


@Override
public int getDefaultDuration() {
return 750;
}
}
8 changes: 8 additions & 0 deletions app/src/main/res/layout/activity_indicator.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
android:onClick="showClick"
/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="durationClick"
android:text="DURATION"
/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Expand Down
54 changes: 32 additions & 22 deletions library/src/main/java/com/wang/avi/AVLoadingIndicatorView.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

public class AVLoadingIndicatorView extends View {

private static final String TAG="AVLoadingIndicatorView";
private static final String TAG = "AVLoadingIndicatorView";

private static final BallPulseIndicator DEFAULT_INDICATOR=new BallPulseIndicator();
private static final BallPulseIndicator DEFAULT_INDICATOR = new BallPulseIndicator();

private static final int MIN_SHOW_TIME = 500; // ms
private static final int MIN_DELAY = 500; // ms
Expand Down Expand Up @@ -63,31 +63,32 @@ public void run() {

private Indicator mIndicator;
private int mIndicatorColor;
private int mAnimationDuration;

private boolean mShouldStartAnimationDrawable;

public AVLoadingIndicatorView(Context context) {
super(context);
init(context, null,0,0);
init(context, null, 0, 0);
}

public AVLoadingIndicatorView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs,0,R.style.AVLoadingIndicatorView);
init(context, attrs, 0, R.style.AVLoadingIndicatorView);
}

public AVLoadingIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs,defStyleAttr,R.style.AVLoadingIndicatorView);
init(context, attrs, defStyleAttr, R.style.AVLoadingIndicatorView);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public AVLoadingIndicatorView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context,attrs,defStyleAttr,R.style.AVLoadingIndicatorView);
init(context, attrs, defStyleAttr, R.style.AVLoadingIndicatorView);
}

private void init(Context context,AttributeSet attrs,int defStyleAttr, int defStyleRes) {
private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
mMinWidth = 24;
mMaxWidth = 48;
mMinHeight = 24;
Expand All @@ -100,10 +101,11 @@ private void init(Context context,AttributeSet attrs,int defStyleAttr, int defSt
mMaxWidth = a.getDimensionPixelSize(R.styleable.AVLoadingIndicatorView_maxWidth, mMaxWidth);
mMinHeight = a.getDimensionPixelSize(R.styleable.AVLoadingIndicatorView_minHeight, mMinHeight);
mMaxHeight = a.getDimensionPixelSize(R.styleable.AVLoadingIndicatorView_maxHeight, mMaxHeight);
String indicatorName=a.getString(R.styleable.AVLoadingIndicatorView_indicatorName);
mIndicatorColor=a.getColor(R.styleable.AVLoadingIndicatorView_indicatorColor, Color.WHITE);
String indicatorName = a.getString(R.styleable.AVLoadingIndicatorView_indicatorName);
mIndicatorColor = a.getColor(R.styleable.AVLoadingIndicatorView_indicatorColor, Color.WHITE);
mAnimationDuration = a.getInteger(R.styleable.AVLoadingIndicatorView_animationDuration, 0);
setIndicator(indicatorName);
if (mIndicator==null){
if (mIndicator == null) {
setIndicator(DEFAULT_INDICATOR);
}
a.recycle();
Expand All @@ -123,13 +125,19 @@ public void setIndicator(Indicator d) {
mIndicator = d;
//need to set indicator color again if you didn't specified when you update the indicator .
setIndicatorColor(mIndicatorColor);
setAnimationDuration(mAnimationDuration);
if (d != null) {
d.setCallback(this);
}
postInvalidate();
}
}

public void setAnimationDuration(int duration) {
this.mAnimationDuration = duration;
mIndicator.setDuration(duration);
}


/**
* setIndicatorColor(0xFF00FF00)
Expand All @@ -141,10 +149,11 @@ public void setIndicator(Indicator d) {
* setIndicatorColor(0xFF00FF00)
* or
* setIndicatorColor(getResources().getColor(android.R.color.black))
*
* @param color
*/
public void setIndicatorColor(int color){
this.mIndicatorColor=color;
public void setIndicatorColor(int color) {
this.mIndicatorColor = color;
mIndicator.setColor(color);
}

Expand All @@ -155,15 +164,16 @@ public void setIndicatorColor(int color){
* 1. Only class Name,like "SimpleIndicator".(This way would use default package name with
* "com.wang.avi.indicators")
* 2. Class name with full package,like "com.my.android.indicators.SimpleIndicator".
*
* @param indicatorName the class must be extend Indicator .
*/
public void setIndicator(String indicatorName){
if (TextUtils.isEmpty(indicatorName)){
public void setIndicator(String indicatorName) {
if (TextUtils.isEmpty(indicatorName)) {
return;
}
StringBuilder drawableClassName=new StringBuilder();
if (!indicatorName.contains(".")){
String defaultPackageName=getClass().getPackage().getName();
StringBuilder drawableClassName = new StringBuilder();
if (!indicatorName.contains(".")) {
String defaultPackageName = getClass().getPackage().getName();
drawableClassName.append(defaultPackageName)
.append(".indicators")
.append(".");
Expand All @@ -174,21 +184,21 @@ public void setIndicator(String indicatorName){
Indicator indicator = (Indicator) drawableClass.newInstance();
setIndicator(indicator);
} catch (ClassNotFoundException e) {
Log.e(TAG,"Didn't find your class , check the name again !");
Log.e(TAG, "Didn't find your class , check the name again !");
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}

public void smoothToShow(){
startAnimation(AnimationUtils.loadAnimation(getContext(),android.R.anim.fade_in));
public void smoothToShow() {
startAnimation(AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_in));
setVisibility(VISIBLE);
}

public void smoothToHide(){
startAnimation(AnimationUtils.loadAnimation(getContext(),android.R.anim.fade_out));
public void smoothToHide() {
startAnimation(AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_out));
setVisibility(GONE);
}

Expand Down
61 changes: 42 additions & 19 deletions library/src/main/java/com/wang/avi/Indicator.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,19 @@

public abstract class Indicator extends Drawable implements Animatable {

private HashMap<ValueAnimator,ValueAnimator.AnimatorUpdateListener> mUpdateListeners=new HashMap<>();
private HashMap<ValueAnimator, ValueAnimator.AnimatorUpdateListener> mUpdateListeners = new HashMap<>();

private ArrayList<ValueAnimator> mAnimators;
private int alpha = 255;
private static final Rect ZERO_BOUNDS_RECT = new Rect();
protected Rect drawBounds = ZERO_BOUNDS_RECT;

private boolean mHasAnimators;
private int mDuration;

private Paint mPaint=new Paint();
private Paint mPaint = new Paint();

public Indicator(){
public Indicator() {
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
Expand Down Expand Up @@ -66,7 +67,7 @@ public void setColorFilter(ColorFilter colorFilter) {

@Override
public void draw(Canvas canvas) {
draw(canvas,mPaint);
draw(canvas, mPaint);
}

public abstract void draw(Canvas canvas, Paint paint);
Expand Down Expand Up @@ -95,8 +96,8 @@ private void startAnimators() {

//when the animator restart , add the updateListener again because they
// was removed by animator stop .
ValueAnimator.AnimatorUpdateListener updateListener=mUpdateListeners.get(animator);
if (updateListener!=null){
ValueAnimator.AnimatorUpdateListener updateListener = mUpdateListeners.get(animator);
if (updateListener != null) {
animator.addUpdateListener(updateListener);
}

Expand All @@ -105,7 +106,7 @@ private void startAnimators() {
}

private void stopAnimators() {
if (mAnimators!=null){
if (mAnimators != null) {
for (ValueAnimator animator : mAnimators) {
if (animator != null && animator.isStarted()) {
animator.removeAllUpdateListeners();
Expand Down Expand Up @@ -143,13 +144,14 @@ public boolean isRunning() {
}

/**
* Your should use this to add AnimatorUpdateListener when
* create animator , otherwise , animator doesn't work when
* the animation restart .
* Your should use this to add AnimatorUpdateListener when
* create animator , otherwise , animator doesn't work when
* the animation restart .
*
* @param updateListener
*/
public void addUpdateListener(ValueAnimator animator, ValueAnimator.AnimatorUpdateListener updateListener){
mUpdateListeners.put(animator,updateListener);
public void addUpdateListener(ValueAnimator animator, ValueAnimator.AnimatorUpdateListener updateListener) {
mUpdateListeners.put(animator, updateListener);
}

@Override
Expand All @@ -166,36 +168,57 @@ public void setDrawBounds(int left, int top, int right, int bottom) {
this.drawBounds = new Rect(left, top, right, bottom);
}

public void postInvalidate(){
public void postInvalidate() {
invalidateSelf();
}

public Rect getDrawBounds() {
return drawBounds;
}

public int getWidth(){
public int getWidth() {
return drawBounds.width();
}

public int getHeight(){
public int getHeight() {
return drawBounds.height();
}

public int centerX(){
public int centerX() {
return drawBounds.centerX();
}

public int centerY(){
public int centerY() {
return drawBounds.centerY();
}

public float exactCenterX(){
public float exactCenterX() {
return drawBounds.exactCenterX();
}

public float exactCenterY(){
public float exactCenterY() {
return drawBounds.exactCenterY();
}

public void setDuration(int duration) {
this.mDuration = duration;
}

public int getDuration() {
if (mDuration<=0) {
return getDefaultDuration();
}
return mDuration;
}

public abstract int getDefaultDuration();

/**
* This is used to multiply the delays so they will be
* in sync with the duration values.
* @return the multiplier.
*/
public float getMultiplier() {
return getDuration() / getDefaultDuration();
}
}