public class LoadAnimationView extends View {
private int width;
private int height;
private int size;
private int length;
private Paint paint;
private float strokeWidth;
private int distanceBoundary;
private int alpha;
private int color;
private final int DEFAULT_ROTATE_DEGREE = 45;
private int degree = DEFAULT_ROTATE_DEGREE;
private boolean isStopped;
public LoadAnimationView(Context context) {
this(context, null);
}
public LoadAnimationView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
if(attrs != null){
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LoadAnimationView);
strokeWidth = typedArray.getFloat(R.styleable.LoadAnimationView_stroke_width,5f);
distanceBoundary = typedArray.getInt(R.styleable.LoadAnimationView_distance_padding,10);
length = typedArray.getInt(R.styleable.LoadAnimationView_length,12);
color = typedArray.getInt(R.styleable.LoadAnimationView_base_color,Color.DKGRAY);
typedArray.recycle();
}
paint = new Paint();
alpha = 150;
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setColor(color);
paint.setAlpha(alpha);
paint.setAntiAlias(true);
paint.setStrokeWidth(strokeWidth);
paint.setStrokeCap(Paint.Cap.ROUND);
new Thread(new Runnable() {
@Override
public void run() {
while (!isStopped) {
try {
Thread.sleep(90);
degree += DEFAULT_ROTATE_DEGREE;
} catch (InterruptedException e) {
e.printStackTrace();
}
LoadAnimationView.this.invalidate();
}
}
}).start();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getMeasuredWidth();
height = getMeasuredHeight();
size = Math.min(width, height);
setMeasuredDimension(size, size);
distanceBoundary = size / 10;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawAnimation(canvas);
}
private void drawAnimation(Canvas canvas) {
canvas.save();
canvas.rotate(degree, size / 2, size / 2);
drawOnce(canvas);
canvas.restore();
}
private void drawOnce(Canvas canvas) {
int startX = size / 2;
int startY = distanceBoundary;
int stopX = size / 2;
int stopY = distanceBoundary + length;
canvas.drawLine(startX, startY, stopX, stopY, paint);
alpha = 150;
for (int i = 0; i < 4; i++) {
alpha -= 15;
paint.setAlpha(alpha);
canvas.rotate(DEFAULT_ROTATE_DEGREE, size / 2, size / 2);
canvas.drawLine(startX, startY, stopX, stopY, paint);
}
alpha -= 15;
for (int j = 0; j < 4; j++) {
paint.setAlpha(alpha);
canvas.rotate(DEFAULT_ROTATE_DEGREE, size / 2, size / 2);
canvas.drawLine(startX, startY, stopX, stopY, paint);
}
}
public void drawIsStopped(boolean isStopped){
if(this.isStopped != isStopped)
this.isStopped = isStopped;
}
}
另外,canvas还有drawBitmap方法
private void drawBitmap(Canvas canvas) {
Rect rect = new Rect((int) distanceBoundary, (int) distanceBoundary, (int) (size - distanceBoundary), (int) (size - distanceBoundary));
if (state) {
canvas.drawBitmap(bitmapPause, null, rect, paintButton);
} else {
canvas.drawBitmap(bitmapStart, null, rect, paintButton);
}
}
drawable转bitmap
public Bitmap decodeBitmapFromResource(Context context, int drawableId) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
return BitmapFactory.decodeResource(context.getResources(), drawableId);
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}