水波浪的自定义控件

//参考了    http://blog.csdn.net/qfanmingyiq/article/details/53038262


public class MyBDView extends View {
    // 波纹颜色
    private static final int WAVE_PAINT_COLOR = 0x33c0c0c0;
    // 底部的高度  注意  底部高度要大于最大的振幅
    private static int BOTTOM_HIGH = 40;
    // 第一个波纹移动的速度
    private int oneSeep = 7;
    // 第二个波纹移动的速度
    private int twoSeep = 13;
    // 第一个波纹移动速度的像素值
    private int oneSeepPxil;
    // 第二个波纹移动速度的像素值
    private int twoSeepPxil;
    // 存放原始波纹的每个y坐标点
    private float wave1[];
    private float wave2[];
    // 存放第一个波纹的每一个y坐标点
    private float oneWave[];
    // 存放第二个波纹的每一个y坐标点
    private float twoWave[];
    // 第一个波纹当前移动的距离
    private int oneNowOffSet;
    // 第二个波纹当前移动的
    private int twoNowOffSet;
    // 振幅高度
    private int amplitude1 = 27;
    private int amplitude2 = 19;
    // 画笔
    private Paint mPaint;
    private Paint mPaintStop;
    // 创建画布过滤
    private DrawFilter mDrawFilter;
    // view的宽度
    private int viewWidth;
    // view高度
    private int viewHeight;
    //
    private boolean flag = false;

    //开始波动
    public void start() {
        flag = true;
        postInvalidate();
    }
    //停止波动
    public void stop() {
        flag = false;
    }
    // xml布局构造方法
    public MyBDView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    // 初始化
    private void init() {
        // 创建画笔
        mPaint = new Paint();
        // 设置画笔颜色
        mPaint.setColor(WAVE_PAINT_COLOR);
        // 设置绘画风格为实线
        mPaint.setStyle(Paint.Style.FILL);
        // 抗锯齿
        mPaint.setAntiAlias(true);
        // 设置划线的粗细
        mPaint.setStrokeWidth(4);
        // 设置图片过滤波和抗锯齿
        mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
        // 第一个波的像素移动值 换算成手机像素值让其在各个手机移动速度差不多
        oneSeepPxil = dpChangPx(oneSeep);
        // 第二个波的像素移动值
        twoSeepPxil = dpChangPx(twoSeep);
        // 创建画笔
        mPaintStop = new Paint();
        // 设置画笔颜色
        mPaintStop.setColor(WAVE_PAINT_COLOR);
        // 设置绘画风格为实线
        mPaintStop.setStyle(Paint.Style.FILL);
        // 抗锯齿
        mPaint.setAntiAlias(true);
        // 设置图片过滤波和抗锯齿
//        mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);

    }

    // 绘画方法
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.setDrawFilter(mDrawFilter);
        oneNowOffSet = oneNowOffSet + oneSeepPxil;
        twoNowOffSet = twoNowOffSet + twoSeepPxil;
        if (oneNowOffSet >= viewWidth) {
            oneNowOffSet = 0;
        }
        if (twoNowOffSet >= viewWidth) {
            twoNowOffSet = 0;
        }
        // 设置波动开始于结束的标记
        if (flag) {
            reSet();
            //i每次  增加4
            for (int i = 0; i < viewWidth; i = i + 4) {
                canvas.drawLine(i, viewHeight, i, viewHeight - BOTTOM_HIGH - oneWave[i], mPaint);
                canvas.drawLine(i, viewHeight, i, viewHeight - BOTTOM_HIGH - twoWave[i], mPaint);
            }
            // 睡眠 10 减少cup 使用  自己测试  配合 上面i +4 在只用这一个控件的情况下 (自己测试)大概减少40% 的cup使用
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            postInvalidate();
        } else {
            for (int i = 0; i < viewWidth; i++) {
                canvas.drawLine(i, viewHeight, i, viewHeight - BOTTOM_HIGH - oneWave[i], mPaintStop);
                canvas.drawLine(i, viewHeight, i, viewHeight - BOTTOM_HIGH - twoWave[i], mPaintStop);
            }
        }
    }
    private void reSet() {
        // one是指 走到此处的波纹的位置 (这个理解方法看个人了)
        int one = viewWidth - oneNowOffSet;
        // 把未走过的波纹放到最前面 进行重新拼接
        System.arraycopy(wave1, oneNowOffSet, oneWave, 0, one);
        // 把已走波纹放到最后
        System.arraycopy(wave1, 0, oneWave, one, oneNowOffSet);
        // one是指 走到此处的波纹的位置 (这个理解方法看个人了)
        int two = viewWidth - twoNowOffSet;
        // 把未走过的波纹放到最前面 进行重新拼接
        System.arraycopy(wave2, twoNowOffSet, twoWave, 0, two);
        // 把已走波纹放到最后
        System.arraycopy(wave2, 0, twoWave, two, twoNowOffSet);
    }
    // 大小改变
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // 获取view的宽高
        viewHeight = h;
        viewWidth = w;
        // 初始化保存波形图的数组
        wave1 = new float[w];
        wave2 = new float[w];
        oneWave = new float[w];
        twoWave = new float[w];
        // 设置波形图周期
        float zq1 = (float) (Math.PI * 4 / w);
        // 设置波形图的周期
        for (int i = 0; i < viewWidth; i++) {
            wave1[i] = (float) (amplitude1 * Math.sin(zq1 * i));
            wave2[i] = (float) (amplitude2 * Math.sin(zq1 * i));
        }
    }
    // dp换算成px 为了让移动速度在各个分辨率的手机的都差不多
    private int dpChangPx(int dp) {
        DisplayMetrics metrics = new DisplayMetrics();
        ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metrics);
        return (int) (metrics.density * dp + 0.5f);
    }
}

你可能感兴趣的:(canvas,控件)