Android圆形水波纹WaveLoading动画

来源:互联网 发布:尚学堂java视频下载 编辑:程序博客网 时间:2024/05/16 01:35

效果图:

这里写图片描述

一、 介绍Paint.setXfermode() 以及PorterDuffXfermode

public class WaveView extends View {    private Paint mWavePaint;    private Paint mCirclePaint;    private Canvas mCanvas;    private Bitmap mBitmap;    private int mWidth;    private int mHeight;    private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.XOR);//设置mode 为XOR    public WaveView(Context context) {        super(context, null);    }    public WaveView(Context context, AttributeSet attrs) {        super(context, attrs, 0);        mWavePaint = new Paint();        mWavePaint.setColor(Color.parseColor("#33b5e5"));        mCirclePaint = new Paint();        mCirclePaint.setColor(Color.parseColor("#99cc00"));        mBitmap = Bitmap.createBitmap(500,500, Bitmap.Config.ARGB_8888); //生成一个bitmap        mCanvas = new Canvas(mBitmap);    }    public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        if (widthMode == MeasureSpec.EXACTLY) {            mWidth = widthSize;        }        if (heightMode == MeasureSpec.EXACTLY) {            mHeight = heightSize;        }        setMeasuredDimension(mWidth, mHeight);    }    @Override    protected void onDraw(Canvas canvas) {        mCanvas.drawCircle(100,100,100,mCirclePaint);        mCanvas.drawRect(100,100,300,300,mWavePaint);        canvas.drawBitmap(mBitmap,200,200,null);        super.onDraw(canvas);    }}

可以看到 是我们现在自己的画布上铺了一个bitmap(这里可以理解canvas为桌子 bitmap为画纸,我们在bimap上画画), 然后在bitmap上画了 一个圆,和一个矩形。最后把我们的mBitmap画到系统的画布上(显示到屏幕上),得到了以下效果。

这里写图片描述

然后我们用setXfermode()方法给他设置一个mode,这里设置SRC_IN。效果如下:

这里写图片描述

总结各个模式如了下图:

我们要实现的是一个圆形的水波纹那种loadingview。。首要就是实现这个水波纹。这时候贝塞尔曲线就派上用场了。这里采用三阶贝塞尔, 不停地改变X 模拟水波效果。

public class WaveLoadingView extends View {    private final Paint mSRCPaint;    private Paint mPaint;    private Paint mTextPaint;    private Canvas mCanvas;    private Bitmap mBitmap;    private int y;    private int x;    private Path mPath;    private boolean isLeft;    private int mWidth;    private int mHeight;    private int mPercent;    private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);    public WaveLoadingView(Context context) {        this(context, null);    }    public WaveLoadingView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public WaveLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mPaint = new Paint();        mPaint.setStrokeWidth(10);        mPaint.setAntiAlias(true);        mPaint.setColor(Color.parseColor("#8800ff66"));        mPath = new Path();        mSRCPaint = new Paint();        mSRCPaint.setAntiAlias(true);        mSRCPaint.setColor(Color.parseColor("#88dddddd"));        mBitmap = Bitmap.createBitmap(getResources().getDimensionPixelSize(R.dimen.bg_size),                getResources().getDimensionPixelSize(R.dimen.bg_size), Bitmap.Config.ARGB_8888);        mCanvas = new Canvas(mBitmap);        mTextPaint = new Paint();        mTextPaint.setAntiAlias(true);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        if (widthMode == MeasureSpec.EXACTLY) {            mWidth = widthSize;        }        if (heightMode == MeasureSpec.EXACTLY) {            mHeight = heightSize;        }        y = mHeight;        setMeasuredDimension(mWidth, mHeight);    }    @Override    protected void onDraw(Canvas canvas) {        if (x > 100) {            isLeft = true;        } else if (x < 0) {            isLeft = false;        }        if (isLeft) {            x = x - 2;        } else {            x = x + 2;        }        mPath.reset();        if (mPercent != 0) {            y = (int) ((1 - mPercent /100f) *mHeight);            mPath.moveTo(0, y);            mPath.cubicTo(100 + x * 2, 50 + y, 100 + x * 2, y - 50, mWidth, y);            mPath.lineTo(mWidth, mHeight);            mPath.lineTo(0, mHeight);            mPath.close();        }        //清除掉图像 不然path会重叠        mBitmap.eraseColor(Color.parseColor("#00000000"));        mCanvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mSRCPaint);        mPaint.setXfermode(mMode);        mCanvas.drawPath(mPath, mPaint);        mPaint.setXfermode(null);        canvas.drawBitmap(mBitmap, 0, 0, null);        mTextPaint.setTextSize(80);        float strLen = mTextPaint.measureText(mPercent + "");        canvas.drawText(mPercent + "", mWidth / 2 - strLen / 2, mHeight / 2+15, mTextPaint);        mTextPaint.setTextSize(40);        canvas.drawText("%", mWidth / 2 + 50, mHeight / 2 - 20, mTextPaint);        postInvalidateDelayed(10);    }    public void setPercent(int percent){        mPercent = percent;    }}

效果如下:
这里写图片描述

0 0
原创粉丝点击