Skip to content

Instantly share code, notes, and snippets.

@cbeyls
Last active January 1, 2019 14:37
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cbeyls/467e1ce10eef73714e5b to your computer and use it in GitHub Desktop.
Save cbeyls/467e1ce10eef73714e5b to your computer and use it in GitHub Desktop.
A custom horizontal indeterminate progress bar which displays a smooth colored animation. (Google Now progress bar)
package android.support.v4.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Handler;
import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
/**
* A custom horizontal indeterminate progress bar which displays a smooth colored animation.
*
* @author Christophe Beyls
*/
public class RefreshProgressBar extends View {
private static final float PROGRESS_BAR_HEIGHT = 4f;
private final Handler handler;
boolean mIsRefreshing = false;
SwipeProgressBar mProgressBar;
private final int mProgressBarHeight;
public RefreshProgressBar(Context context) {
this(context, null, 0);
}
public RefreshProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RefreshProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
handler = new Handler();
if (!isInEditMode()) {
mProgressBar = new SwipeProgressBar(this);
}
final DisplayMetrics metrics = getResources().getDisplayMetrics();
mProgressBarHeight = (int) (metrics.density * PROGRESS_BAR_HEIGHT + 0.5f);
}
/**
* Starts or tops the refresh animation. Animation is stopped by default. After the stop animation has completed,
* the progress bar will be fully transparent.
*/
public void setRefreshing(boolean refreshing) {
if (mIsRefreshing != refreshing) {
mIsRefreshing = refreshing;
handler.removeCallbacks(mRefreshUpdateRunnable);
handler.post(mRefreshUpdateRunnable);
}
}
private final Runnable mRefreshUpdateRunnable = new Runnable() {
@Override
public void run() {
if (mIsRefreshing) {
mProgressBar.start();
} else {
mProgressBar.stop();
}
}
};
@Override
protected void onDetachedFromWindow() {
handler.removeCallbacks(mRefreshUpdateRunnable);
super.onDetachedFromWindow();
}
/**
* Set the four colors used in the progress animation from color resources.
*/
public void setColorSchemeResources(@ColorRes int colorRes1, @ColorRes int colorRes2, @ColorRes int colorRes3, @ColorRes int colorRes4) {
final Context context = getContext();
setColorSchemeColors(ContextCompat.getColor(context, colorRes1), ContextCompat.getColor(context, colorRes2),
ContextCompat.getColor(context, colorRes3), ContextCompat.getColor(context, colorRes4));
}
/**
* Set the four colors used in the progress animation.
*/
public void setColorSchemeColors(@ColorInt int color1, @ColorInt int color2, @ColorInt int color3, @ColorInt int color4) {
mProgressBar.setColorScheme(color1, color2, color3, color4);
}
/**
* @return Whether the progress bar is actively showing refresh progress.
*/
public boolean isRefreshing() {
return mIsRefreshing;
}
@Override
public void draw(@NonNull Canvas canvas) {
super.draw(canvas);
if (mProgressBar != null) {
mProgressBar.draw(canvas);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (mProgressBar != null) {
mProgressBar.setBounds(0, 0, getWidth(), getHeight());
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), mProgressBarHeight);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment