继续使用PorterDuffXfermode的图形混合模式,对于不了解图形混合模式的,请移步爱哥的博客,爱哥关于图形混合模式的讲解然后加入了三次贝塞尔曲线。对于三次贝塞尔曲线不了解的自行百度吧。
对于PorterDuffXfermode使用的是SRC_IN的mode模式。
还是自定义View的老路子:
onMeasure()方法:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
throw new IllegalArgumentException("请把宽写确定!");
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
throw new IllegalArgumentException("请把高写确定!");
}
setMeasuredDimension(width, height);
min = Math.min(width, height);
mBitmap = Bitmap.createBitmap(min, min, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
然后重写onDraw()方法:
@Override
protected void onDraw(Canvas canvas) {
mCanvas.drawCircle(min / 2, min / 2, min / 2, circlePaint);//目标图
wavePaint.setXfermode(porterDuffXfermode);
if (x > 0.35) {
x -= 0.2;
} else {
x += 0.1;
}
if (y >= (1 - finish / 100f)) {
y -= 0.01;
}
mPath.reset();//防止路径重叠
mPath.moveTo(0, (float) (min * y));
mPath.cubicTo(min * x, (min * y) + (min / 10), (min * x) + (min / 2), min * y - (min / 10), min, min * y);
mPath.lineTo(min, min);
mPath.lineTo(0, min);
mPath.close();
mCanvas.drawPath(mPath, wavePaint);
canvas.drawBitmap(mBitmap, 0, 0, null);
postInvalidateDelayed(100);
}
贴一下完整代码:
public class DefineLoadingView extends View {
/**
* 图像混合模式
*/
private PorterDuffXfermode porterDuffXfermode;
/**
* 创建一个Bitmap
*/
private Bitmap mBitmap;
/**
* 画布
*/
private Canvas mCanvas;
/**
* View的宽
*/
private int width;
/**
* View的高
*/
private int height;
/**
* 画笔
*/
private Paint wavePaint, circlePaint;
/**
* 路径对象
*/
private Path mPath;
private float x;
private float y = 1f;
private int min;
public DefineLoadingView(Context context) {
this(context, null);
}
public DefineLoadingView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DefineLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initRecrouse();
}
/**
* 初始化资源
*/
private void initRecrouse() {
wavePaint = new Paint();
wavePaint.setAntiAlias(true);
wavePaint.setColor(Color.GREEN);
circlePaint = new Paint();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.parseColor("#77aa0000"));
// setLayerType(LAYER_TYPE_SOFTWARE, null);//关闭硬件加速
//设置图像混合模式
porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
mPath = new Path();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
throw new IllegalArgumentException("请把宽写确定!");
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
throw new IllegalArgumentException("请把高写确定!");
}
setMeasuredDimension(width, height);
min = Math.min(width, height);
mBitmap = Bitmap.createBitmap(min, min, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
mCanvas.drawCircle(min / 2, min / 2, min / 2, circlePaint);//目标图
wavePaint.setXfermode(porterDuffXfermode);
if (x > 0.35) {
x -= 0.2;
} else {
x += 0.1;
}
if (y >= (1 - finish / 100f)) {
y -= 0.01;
}
mPath.reset();//防止路径重叠
mPath.moveTo(0, (float) (min * y));
mPath.cubicTo(min * x, (min * y) + (min / 10), (min * x) + (min / 2), min * y - (min / 10), min, min * y);
mPath.lineTo(min, min);
mPath.lineTo(0, min);
mPath.close();
mCanvas.drawPath(mPath, wavePaint);
canvas.drawBitmap(mBitmap, 0, 0, null);
postInvalidateDelayed(100);
}
private int finish;
boolean isleft;
/***
* 设置完成度
*
* @param finish
*/
public void setFinnish(int finish) {
this.finish = finish;
}
}
每天进步一点点