Android Custom View --- 水波纹效果

版权声明:本文为博主原创文章,转载需注明博主文章链接。 https://blog.csdn.net/black_bread/article/details/63254487

参考链接:Android 自定义view实现水波纹效果

偷了张效果图:
这里写图片描述

看完参考链接之后,发现效率有点差了,每次都绘制2*屏幕宽度次的line,强迫症的我啊。。这里写图片描述

方法一:

每次都绘制line来生成图片也太鸡肋了,在onSizeChange中生成一张Bitmap用于onDraw方法中

onSizeChange方法

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        mWidth = w;
        mHeight = h;

        mWave = new int[mWidth];

        float period = (float) (2 * Math.PI / mWidth);

        for (int index = 0; index < mWave.length; index ++) {
            mWave[index] = (int) (mAWave + mAWave * Math.sin(period * index));
        }

        mCacheBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mCacheBitmap);
        canvas.setDrawFilter(mDrawFilter);
        for (int index = 0; index < mWave.length; index++ ) {
            canvas.drawLine(index, mWave[index], index, mHeight, mPaint);
        }

        mWave = null;
    }

onDraw方法

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        long l = System.currentTimeMillis();

        canvas.setDrawFilter(mDrawFilter);

        mFirstOffset += mFirstWaveSpeed;
        if(mFirstOffset > mWidth) {
            mFirstOffset -= mWidth;
        }
        mSecondOffset += mSecondWaveSpeed;
        if (mSecondOffset > mWidth) {
            mSecondOffset -= mWidth;
        }

        canvas.drawBitmap(mCacheBitmap, mSecondOffset, 0, mPaint);
        canvas.drawBitmap(mCacheBitmap, mSecondOffset - mWidth + 1, 0, mPaint);
        canvas.drawBitmap(mCacheBitmap, mFirstOffset, 0, mPaint);
        canvas.drawBitmap(mCacheBitmap, mFirstOffset - mWidth + 1, 0, mPaint);

        invalidate();

        long e = System.currentTimeMillis();
        Log.e(TAG, "onDraw: " + (e - l));
    }

查看在OnDraw中绘制耗费的时长,效率还不错,缩减了一半时长,但是发现居然有锯齿。。该设置的都设置了。。。

这里写图片描述

方法二:

用line绘制的有锯齿,那就用path画个没锯齿的,选择三阶贝赛尔曲线绘制

onSizeChange方法

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        mWidth = w;
        mHeight = h;

        mCacheBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mCacheBitmap);
        canvas.setDrawFilter(mDrawFilter);

        Path path = new Path();
        int A = TransformUnitUtil.dip2px(getContext(), mAWave);
        path.reset();
        path.moveTo(mWidth / 2, A);
        path.quadTo(mWidth - mWidth /4, 2 * A, mWidth, A);
        canvas.clipPath(path, Region.Op.XOR);  //裁除交集部分,要在绘制canvas之前clip,如果绘制之后进行clip不会影响到已经画好的图形
        //除此之外,cavas.clipPath不支持硬件加速,必须在AndroidManifest.xml中添加android:hardwareAccelerated="false",不然效果出不来

        path.reset();
        path.moveTo(0, A);
//        path.cubicTo(mWidth / 4, 0, mWidth - mWidth / 4, 2 * A, mWidth, A);
        path.quadTo(mWidth / 4, 0, mWidth / 2, A);
        canvas.drawPath(path, mPaint);

        canvas.drawRect(0, A, mWidth/2, mHeight, mPaint);
        canvas.drawRect(mWidth / 2, A, mWidth, mHeight, mPaint);

        mWave = null;

    }

搞定!!!

完整代码:

package com.example.yinhua.myapplication.custome;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.example.yinhua.myapplication.utils.TransformUnitUtil;

/**
 * Created by yinhua on 2017/3/18.
 */

public class WaveView extends View {

    private static final String TAG = WaveView.class.getSimpleName();
    private static final int WAVE_COLOR = 0xDD0000AA;

    private int mWidth;   //View宽
    private int mHeight;  //View高
    private int mFirstWaveSpeed;    //第一个水波纹的偏移速度
    private int mSecondWaveSpeed;   //第二个水波纹的偏移速度
    private int mAWave = 10;            //水波纹的振幅
    private int[] mWave;                //水波纹数组
    private int mFirstOffset;       //第一个水波纹偏移
    private int mSecondOffset;       //第一个水波纹偏移

    private Paint mPaint;
    private DrawFilter mDrawFilter;
    private Bitmap mCacheBitmap;

    public WaveView(Context context) {
        this(context, null);
    }

    public WaveView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

        initSpeed();
        initDrawTools();
    }

    /**
     * 初始化偏移速度
     */
    private void initSpeed() {
        mFirstWaveSpeed = TransformUnitUtil.dip2px(getContext(), 4);
        mSecondWaveSpeed = TransformUnitUtil.dip2px(getContext(), 5);
    }

    /**
     * 初始化绘图工具
     */
    private void initDrawTools() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(WAVE_COLOR);

        mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        mWidth = w;
        mHeight = h;

//        mWave = new int[mWidth];

//        float period = (float) (2 * Math.PI / mWidth);

//        for (int index = 0; index < mWave.length; index ++) {
//            mWave[index] = (int) (mAWave + mAWave * Math.sin(period * index));
//        }

        mCacheBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mCacheBitmap);
        canvas.setDrawFilter(mDrawFilter);
//        for (int index = 0; index < mWave.length; index++ ) {
//            canvas.drawLine(index, mWave[index], index, mHeight, mPaint);
//        }

        Path path = new Path();
        int A = TransformUnitUtil.dip2px(getContext(), mAWave);
        path.reset();
        path.moveTo(mWidth / 2, A);
        path.quadTo(mWidth - mWidth /4, 2 * A, mWidth, A);
        canvas.clipPath(path, Region.Op.XOR);  //裁除交集部分,要在绘制canvas之前clip,如果绘制之后进行clip不会影响到已经画好的图形
        //除此之外,cavas.clipPath不支持硬件加速,必须在AndroidManifest.xml中添加android:hardwareAccelerated="false",不然效果出不来

        path.reset();
        path.moveTo(0, A);
//        path.cubicTo(mWidth / 4, 0, mWidth - mWidth / 4, 2 * A, mWidth, A);
        path.quadTo(mWidth / 4, 0, mWidth / 2, A);
        canvas.drawPath(path, mPaint);

        canvas.drawRect(0, A, mWidth/2, mHeight, mPaint);
        canvas.drawRect(mWidth / 2, A, mWidth, mHeight, mPaint);

        mWave = null;

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        long l = System.currentTimeMillis();
//        Log.e(TAG, "onDraw: " + l);
        canvas.setDrawFilter(mDrawFilter);

        mFirstOffset += mFirstWaveSpeed;
        if(mFirstOffset > mWidth) {
            mFirstOffset -= mWidth;
        }
        mSecondOffset += mSecondWaveSpeed;
        if (mSecondOffset > mWidth) {
            mSecondOffset -= mWidth;
        }

        canvas.drawBitmap(mCacheBitmap, mSecondOffset, 0, mPaint);
        canvas.drawBitmap(mCacheBitmap, mSecondOffset - mWidth + 1, 0, mPaint);
        canvas.drawBitmap(mCacheBitmap, mFirstOffset, 0, mPaint);
        canvas.drawBitmap(mCacheBitmap, mFirstOffset - mWidth + 1, 0, mPaint);

        invalidate();   //考虑延迟几秒之后再刷新绘制

        long e = System.currentTimeMillis();
        Log.e(TAG, "onDraw: " + (e - l));
    }
}

猜你喜欢

转载自blog.csdn.net/black_bread/article/details/63254487