自定义水波纹的View

继续使用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;
    }
}

每天进步一点点

猜你喜欢

转载自blog.csdn.net/ljngya/article/details/52851529
今日推荐