Android 水波纹效果


csdn上关于水波纹的demo很多,实现方法也很多,这里我是根据正弦函数生成的,及供参考。。。。

上代码:

/*绘图*/
    private Paint paint ;        // 画波浪的画笔
    private Paint mCirclePaint;  // 画圆的画笔
    private Paint mTextPaint ;    // 画字的画笔
    private Canvas mCanvas;                    // 画布
    private Bitmap mBitmap;                    //
    int time = 0;               // 控制波浪波动的快慢
    int width ,height;
    private int mPercent ;       // 百分比
    private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);//设置mode 为XOR


    private String mText;
    private float mTextSize;
    private int mTextColor;
    private boolean mTextVisible = true;
    private int mWaveBackgroud;         // 波浪颜色
    private int mWaveBottomColor;       // 波浪底色

    public WaveView1(Context context) {
        super(context);
    }

    public WaveView1(Context context, AttributeSet attrs) {
        super(context, attrs,0);
        initView(attrs);
    }

    public WaveView1(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(attrs);

    }

    public void initView(AttributeSet attrs){

        TypedArray typedArray = getContext().obtainStyledAttributes(attrs,R.styleable.WaveView1);
        mWaveBottomColor = typedArray.getColor(R.styleable.WaveView1_waveBottomColor,Color.parseColor("#88dddddd"));
        mWaveBackgroud = typedArray.getColor(R.styleable.WaveView1_waveBackgroud,Color.parseColor("#53ff42"));
        mText = typedArray.getString(R.styleable.WaveView1_text);
        mTextColor = typedArray.getColor(R.styleable.WaveView1_textColor,Color.parseColor("#000000"));
        mTextSize = typedArray.getDimension(R.styleable.WaveView1_textSize,24);
        mTextVisible = typedArray.getBoolean(R.styleable.WaveView1_textVisible,true);
        typedArray.recycle();

        paint = new Paint();
        paint.setColor(mWaveBottomColor);
        // 设置宽度
        paint.setStrokeWidth(3);
        // 设置样式
        paint.setStyle(Paint.Style.FILL);
        // 抗锯齿
        paint.setAntiAlias(true);


        mCirclePaint = new Paint();
        mCirclePaint.setColor(mWaveBackgroud);
        mCirclePaint.setAntiAlias(true);

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setTextSize(mTextSize);
        mTextPaint.setColor(mTextColor);

        Log.d(TAG,"*****  initView  ******");

    }

    @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) {
            width = widthSize;
        }
        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        }

        // TODO 放在相对布局中 width 和 height 等于0 ????????
        if (width == 0 || height == 0){
            width = 500;
            height = 500;
        }
        Log.d(TAG, "width == " + width + "  height == " + height);
        mBitmap = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888); //生成一个bitmap
        mCanvas = new Canvas(mBitmap);//讲bitmp放在我们自己的画布上,实际上mCanvas.draw的时候 改变的是这个bitmap对象
        setMeasuredDimension(width, height);
    }

先是这些准备工作,画笔画布,自定义属性等等。。。


最主要的还是onDraw方法:

@Override
    protected void onDraw(Canvas canvas) {

        // TODO 周期性变化
        time += 20;
//        time ++ ;
        if (time == 360){ // TODO 三角函数知识 周期性  不解释。。。
            time = 0;
        }

        int pointX = 0;
        int pointY = 0;

        // TODO 清除掉图像,不然波纹交界处有阴影  加上颜色会变得淡一些
        mBitmap.eraseColor(Color.parseColor("#00000000"));
        mCanvas.drawCircle(width/2,height/2,height/2,mCirclePaint);
        // TODO 设置重叠模式
        paint.setXfermode(mMode);

        if (mPercent == 0){
            // 进度为 0 不画
        }else if ( mPercent >= 100){
            // 全部画满
            while (pointX < width){
                pointY = 0;
                mCanvas.drawLine(pointX,pointY,pointX,height,paint);
                pointX ++;
            }

        }else{

            while (pointX < width){
                pointY = (int) (15 * Math.sin((pointX - time)* Math.PI / 180)) + (height - height * mPercent/100);
                mCanvas.drawLine(pointX,pointY,pointX,height,paint);
                pointX ++;
            }
        }
        postInvalidateDelayed(100);
        canvas.drawBitmap(mBitmap,0,0,null);

        // TODO 画字
        if (mTextVisible){
            canvas.drawText(mPercent + " %",width/2 - 12,height/2 + 12,mTextPaint);
        }
        super.onDraw(canvas);

    }

整个的原理就是根据正弦函数的周期性有规律的波动,如果想调节波动的速率,有两个地方:

1. time参数,time参数越大,函数变化越明显,正弦函数得知识应该都还没忘吧。。。

2. 

postInvalidateDelayed(100);

这个地方是设置view重绘的时间,最好还是时间长一点吧,在波动的过程中一直在重绘

当然设置view的动态效果可以有多种,可以用Handler  或者 Thread + runnable,我的源码里也有,可以参考参考


还有关于  PorterDuffXfermode 设置遮盖模式,自己用代码实现一下,很好理解:


源码地址:http://download.youkuaiyun.com/detail/qq55214/9630956



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值