圆形水波控件

圆形水波控件


        圆形水波控件,看起来就觉得很牛b的样子。水波是利用贝塞尔曲线的原理绘制的。效果图如下:



看上去是不是很牛的样子,哈哈...


想都不用想这是一个自定义控件,如下:

public class WaveView extends View {
    private static final int CONTROL_SIZE = 600;  //控件大小
    private Paint backgroundPaint;
    private Paint firstWavePaint;
    private Paint secondWavePaint;
    private int backgroundColor;
    private int firstWaveColor;
    private int secondWaveColor;
    private Path firstPath;
    private Path secondPath;
    private Bitmap bitmap;
    private Canvas bitmapCanvas;
    private int speed;          //水波的速度
    private int amplitude;      //振幅 ---- 水波的最高点和最低点
    private static final float palstance = 0.5F;    //角速度
    private static final float waterProgressMax = 100;  //最高水位
    private float waterProgress;    //水位高度 --- 0~100
    private int waveSize;     //控件尺寸
    private int angle;
    private static final int whatStartWave = 100;   //开始 波动水位
    private WaveHandler waveHandler;
    private WaveThread waveThread;
    private boolean canLoopWave;
    private String name = "电量";
    private Paint textPaint;
    private Rect rect;

    public WaveView(Context context) {
        super(context);
        initView(null);
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(waveSize, waveSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        firstPath.reset();
        secondPath.reset();
        bitmapCanvas.drawCircle(waveSize / 2, waveSize / 2, waveSize / 2, backgroundPaint);
        /**水位线*/
        float waterLine = (waterProgressMax - waterProgress) * waveSize * 0.01F;
        /* x、y*/
        firstPath.moveTo(0, waterLine);
        secondPath.moveTo(0, waterLine);
        int x1 = 0;
        int y1 = 0;
        int x2 = 0;
        int y2 = 0;
        for (int i = 0; i < waveSize; i++) {   //x轴数据的集合
            x1 = i;
            x2 = i;
            //轴数据对应的y值 --- 正弦曲线 y = sin(X);
            y1 = (int) (amplitude * Math.sin((i * palstance + angle) * Math.PI / 180) + waterLine);
            y2 = (int) (amplitude * Math.sin((i * palstance + angle - 90) * Math.PI / 180) + waterLine);
            firstPath.quadTo(x1, y1, x1 + 1, y1);
            secondPath.quadTo(x2, y2, x2 + 1, y2);
        }
        firstPath.lineTo(waveSize, waveSize);
        firstPath.lineTo(0, waveSize);
        firstPath.close();
        secondPath.lineTo(waveSize, waveSize);
        secondPath.lineTo(0, waveSize);
        secondPath.close();
        bitmapCanvas.drawPath(firstPath, firstWavePaint);
        bitmapCanvas.drawPath(secondPath, secondWavePaint);
        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
        canvas.drawBitmap(bitmap, 0, 0, null);

        String progress = (int) waterProgress + "%";
        textPaint.getTextBounds(progress, 0, progress.length(), rect);
        int progressWidth = rect.width();
        textPaint.getTextBounds(name, 0, name.length(), rect);
        int textWidth = rect.width();
        textPaint.setTextSize(60);
        if (waterProgress<35){
            textPaint.setColor(Color.BLACK);
        }else {
            textPaint.setColor(Color.WHITE);
        }
        canvas.drawText(name, waveSize / 2 - textWidth / 2, waveSize * 3 / 4, textPaint);         //把name画上去
        if (waterProgress<70){
            textPaint.setColor(Color.BLACK);
        }else {
            textPaint.setColor(Color.WHITE);
        }
        canvas.drawText(progress, waveSize / 2 - progressWidth / 2, waveSize * 2 / 5, textPaint);        //画进度值
    }

    private void initView(AttributeSet attrs) {
        angle = 360;
        canLoopWave = true;
        waterProgress = 0;
        Context context = getContext();
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.wave_view);
        backgroundColor = typedArray.getColor(R.styleable.wave_view_backgroundColor, Color.parseColor("#44EEEEEE"));
        firstWaveColor = typedArray.getColor(R.styleable.wave_view_firstWaveColor, Color.parseColor("#C3F5FE"));
        secondWaveColor = typedArray.getColor(R.styleable.wave_view_secondWaveColor, Color.parseColor("#43DCFE"));
        waterProgress = typedArray.getFloat(R.styleable.wave_view_waterProgress, 0);
        amplitude = typedArray.getInt(R.styleable.wave_view_amplitude, dpToPx(20));
        speed = typedArray.getInt(R.styleable.wave_view_speed, 1);
        waveSize = typedArray.getDimensionPixelSize(R.styleable.wave_view_waveSize, CONTROL_SIZE);
        waveThread = new WaveThread();
        waveHandler = new WaveHandler();
        backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        backgroundPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        backgroundPaint.setColor(backgroundColor);
        backgroundPaint.setAntiAlias(true);
        bitmap = Bitmap.createBitmap(waveSize, waveSize, Bitmap.Config.ARGB_8888);
        bitmapCanvas = new Canvas(bitmap);
        bitmapCanvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
        /*初始化波浪画笔*/
        firstWavePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        firstWavePaint.setAntiAlias(true);
        firstWavePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        firstWavePaint.setColor(firstWaveColor);
        /**
         * 该方法用来设置两张图片相交时的模式
         * SRC_ATOP : 取下层非交集部分与上层交集部分
         */
        firstWavePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));

        secondWavePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        secondWavePaint.setAntiAlias(true);
        secondWavePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        secondWavePaint.setColor(secondWaveColor);
        secondWavePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
        firstPath = new Path();
        secondPath = new Path();

        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setAntiAlias(true);
        textPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        textPaint.setColor(Color.BLACK);
        rect = new Rect();              //创建矩形对象

        waveThread.start();             //开启线程
    }

    public void startThread() {
        if (waveThread != null && waveThread.isInterrupted()) {
            waveThread.start();
        }
    }

    /**
     * 设置 水位的进度 [0-100]
     * @param waterProgress 水位进度
     */
    public WaveView setWaterProgress(float waterProgress) {
        if (waterProgress <= 0) {
            waterProgress = 0;
        } else if (waterProgress >= 100) {
            waterProgress = 100;
        }
        this.waterProgress = waterProgress;
        invalidate();
        return this;
    }

    /**
     * 设置第一条波浪线的 颜色
     */
    public WaveView setFirstWaveColor(int firstWaveColor) {
        this.firstWaveColor = firstWaveColor;
        firstWavePaint.setColor(firstWaveColor);
        invalidate();
        return this;
    }

    /**
     * 设置第二条波浪线的 颜色
     */
    public WaveView setSecondWaveColor(int secondWaveColor) {
        this.secondWaveColor = secondWaveColor;
        secondWavePaint.setColor(secondWaveColor);
        invalidate();
        return this;
    }

    /**
     * 设置 波动速读
     */
    public WaveView setSpeed(int speed) {
        if (speed < 1) {
            speed = 1;
        }
        if (speed > 10) {
            speed = 10;
        }
        this.speed = speed;
        return this;
    }


    /**
     * 波浪 波动的 线程
     */
    private class WaveThread extends Thread {

        @Override
        public void run() {
            super.run();
            while (canLoopWave) {
                angle = angle - 1 * speed;
                if (angle == 0) {
                    angle = 360;
                }
                waveHandler.removeCallbacksAndMessages(null);
                waveHandler.sendEmptyMessage(whatStartWave);
                SystemClock.sleep(10);
            }
        }
    }

    /**
     * 波浪 波动的 操作者
     */
    private class WaveHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (whatStartWave == msg.what) {
                invalidate();
            }
        }
    }

    /**
     * 设置 振幅
     * @param amplitude 单位 dp
     */
    public WaveView setAmplitude(int amplitude) {
        if (amplitude <= 0) {
            amplitude = 0;
        }
        this.amplitude = amplitude;
        invalidate();
        return this;
    }

    /**
     * 数据转换: dp---->px
     */
    private int dpToPx(float dp) {
        return (int) (dp * getContext().getResources().getDisplayMetrics().density);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        stopThread();
    }

    public void stopThread() {
        canLoopWave = false;
        if (waveThread != null) {
            waveThread.interrupt();
            waveThread = null;
        }
        if (waveHandler != null) {
            waveHandler.removeMessages(whatStartWave);
            waveHandler = null;
        }
    }
}

资源文件
<resources>
    <declare-styleable name="wave_view">
        <attr name="backgroundColor" format="color" />
        <attr name="firstWaveColor" format="color" />
        <attr name="secondWaveColor" format="color" />
        <attr name="waveSize" format="dimension" />
        <attr name="waterProgress" format="float" />
        <!-- 10 到 50之间比较合适-->
        <attr name="amplitude" format="integer" />
        <!-- 1 到 6 之间比较合适 -->
        <attr name="speed" format="integer" />
    </declare-styleable>
</resources>

MainActivity:模拟充电过程
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        progress++;
        wv.setWaterProgress(progress);
        if (progress <100){
            if (progress <= 20){
                wv.setFirstWaveColor(0xfffda8a8);
                wv.setSecondWaveColor(0xffff0000);
            }else {
                wv.setFirstWaveColor(0xffacfdac);
                wv.setSecondWaveColor(0xff00ff00);
            }
            method();
        }else {
            wv.setSpeed(0);
            wv.setAmplitude(0);
        }
    }
},500);

是不是很牛b的样子,心动了吧,还等什么。自己去试试吧。顺手点个赞,谢谢....




  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值