Skip to content
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();
}
}
Loading