Skip to content

Instantly share code, notes, and snippets.

@bladeFury
Last active June 24, 2019 14:26
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bladeFury/d679503ca4c94fa8d2a8 to your computer and use it in GitHub Desktop.
Save bladeFury/d679503ca4c94fa8d2a8 to your computer and use it in GitHub Desktop.
a round clip drawable which can be used by progressbar
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
/**
* Round Clip Drawable
* like ClipDrawable, but with round corner
* Created by zhangge on 14-8-5.
*/
public class RoundClipDrawable extends Drawable implements Drawable.Callback{
private final Rect mTmpRect = new Rect();
private final Path mTmpPath = new Path();
private float[] mRadius;
private final RectF mTmpRectF = new RectF();
private ClipState mClipState;
/**
* @param drawable
*/
public RoundClipDrawable(Drawable drawable, float radius) {
this(null, null);
float[] radii = null;
if (radius > 0) {
radii = new float[8];
for (int i = 0; i < 8; i++) {
radii[i] = radius;
}
}
mRadius = radii;
mClipState.mDrawable = drawable;
}
// overrides from Drawable.Callback
public void invalidateDrawable(Drawable who) {
if (Build.VERSION.SDK_INT >= 11) {
final Callback callback = getCallback();
if (callback != null) {
callback.invalidateDrawable(this);
}
}
}
public void scheduleDrawable(Drawable who, Runnable what, long when) {
if (Build.VERSION.SDK_INT >= 11) {
final Callback callback = getCallback();
if (callback != null) {
callback.scheduleDrawable(this, what, when);
}
}
}
public void unscheduleDrawable(Drawable who, Runnable what) {
if (Build.VERSION.SDK_INT >= 11) {
final Callback callback = getCallback();
if (callback != null) {
callback.unscheduleDrawable(this, what);
}
}
}
// overrides from Drawable
// overrides from Drawable
@Override
public int getChangingConfigurations() {
return super.getChangingConfigurations()
| mClipState.mChangingConfigurations
| mClipState.mDrawable.getChangingConfigurations();
}
@Override
public boolean getPadding(Rect padding) {
// XXX need to adjust padding!
return mClipState.mDrawable.getPadding(padding);
}
@Override
public boolean setVisible(boolean visible, boolean restart) {
mClipState.mDrawable.setVisible(visible, restart);
return super.setVisible(visible, restart);
}
@Override
public void setAlpha(int alpha) {
mClipState.mDrawable.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
mClipState.mDrawable.setColorFilter(cf);
}
@Override
public int getOpacity() {
return mClipState.mDrawable.getOpacity();
}
@Override
public boolean isStateful() {
return mClipState.mDrawable.isStateful();
}
@Override
protected boolean onStateChange(int[] state) {
return mClipState.mDrawable.setState(state);
}
@Override
protected boolean onLevelChange(int level) {
mClipState.mDrawable.setLevel(level);
invalidateSelf();
return true;
}
@Override
protected void onBoundsChange(Rect bounds) {
mClipState.mDrawable.setBounds(bounds);
}
@Override
public int getIntrinsicWidth() {
return mClipState.mDrawable.getIntrinsicWidth();
}
@Override
public int getIntrinsicHeight() {
return mClipState.mDrawable.getIntrinsicHeight();
}
@Override
public ConstantState getConstantState() {
if (mClipState.canConstantState()) {
mClipState.mChangingConfigurations = getChangingConfigurations();
return mClipState;
}
return null;
}
@Override
public void draw(Canvas canvas) {
final Rect r = mTmpRect;
final Rect bounds = getBounds();
int level = getLevel();
int w = bounds.width();
mTmpPath.reset();
final int iw = 0; //mClipState.mDrawable.getIntrinsicWidth();
w -= (w - iw) * (10000 - level) / 10000;
int h = bounds.height();
r.set(bounds);
r.right = r.left + w;
mTmpRectF.set(r);
mTmpPath.addRoundRect(mTmpRectF, mRadius, Path.Direction.CW);
if (w > 0 && h > 0) {
canvas.save();
canvas.clipPath(mTmpPath);
mClipState.mDrawable.draw(canvas);
canvas.restore();
}
}
final static class ClipState extends ConstantState {
Drawable mDrawable;
int mChangingConfigurations;
private boolean mCheckedConstantState;
private boolean mCanConstantState;
ClipState(ClipState orig, RoundClipDrawable owner, Resources res) {
if (orig != null) {
if (res != null) {
mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
} else {
mDrawable = orig.mDrawable.getConstantState().newDrawable();
}
mDrawable.setCallback(owner);
mCheckedConstantState = mCanConstantState = true;
}
}
@Override
public Drawable newDrawable() {
return new RoundClipDrawable(this, null);
}
@Override
public Drawable newDrawable(Resources res) {
return new RoundClipDrawable(this, res);
}
@Override
public int getChangingConfigurations() {
return mChangingConfigurations;
}
boolean canConstantState() {
if (!mCheckedConstantState) {
mCanConstantState = mDrawable.getConstantState() != null;
mCheckedConstantState = true;
}
return mCanConstantState;
}
}
private RoundClipDrawable(ClipState state, Resources res) {
mClipState = new ClipState(state, this, res);
}
}
@lan603168
Copy link

thank you so much.......helpful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment