android自定义圆形抖动(缩放)视图

转载请注明出处:https://blog.csdn.net/u011038298/article/details/84786307 

import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    // 声明一个圆形抖动(缩放)视图
    private CircleShakeView circleShakeView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 控件的大小(宽/高)
        float size = getResources().getDimension(R.dimen.width34px);
        // 抖动缩放距离
        float shakeDistance = getResources().getDimension(R.dimen.width8px);
        // 外圆半径与内圆半径直接的距离
        float circleDistance = getResources().getDimension(R.dimen.width6px);
        // 获取自定义圆形抖动(缩放)视图
        circleShakeView = findViewById(R.id.circle_shake_view);
        // 设置延迟显示时间(单位:毫秒)  例如延迟20s后再显示红点缩放抖动效果
        circleShakeView.setDelayTime(1000 * 20);
        // 设置圆的抖动(缩放)距离
        circleShakeView.setShakeDistance(shakeDistance);
        // 设置内圆颜色
        circleShakeView.setInsideColor(Color.RED);
        // 设置外圆颜色
        circleShakeView.setOuterColor(Color.WHITE);
        // 设置内圆半径
        circleShakeView.setInsideRadius(size / 2 - circleDistance);
        // 设置外圆半径
        circleShakeView.setOuterRadius(size / 2);
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 开始
        circleShakeView.start();
    }

    @Override
    protected void onStop() {
        super.onStop();
        // 停止
        circleShakeView.stop();
    }

}
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 * 自定义圆形抖动(缩放)视图
 */

public class CircleShakeView extends View {

    public CircleShakeView(Context context) {
        super(context);
        init();
    }

    public CircleShakeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CircleShakeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    // 外圆半径
    private float outerRadius;
    // 内圆半径(小于外圆半径)
    private float insideRadius;
    // 抖动缩放的距离
    private float shakeDistance;
    // 当前抖动缩放的距离
    private float curDistance;

    // 外圆颜色
    private int outerColor;
    // 内圆颜色
    private int insideColor;

    // 画笔
    private Paint mPaint;

    // 延迟抖动时间
    private long delayTime;
    // 是否允许绘制
    private boolean isDraw;
    // 是否开始运行
    private volatile boolean isRun;
    // 声明一个线程
    private Thread mThread;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (isInEditMode()) {
            return;
        }
        if (!isDraw) {
            return;
        }
        if (outerRadius > insideRadius) {
            // 绘制外圆(圆心不变,半径发生变化)
            RectF outerRectF = new RectF();
            outerRectF.left = curDistance;
            outerRectF.right = outerRadius * 2 - curDistance;
            outerRectF.top = curDistance;
            outerRectF.bottom = outerRadius * 2 - curDistance;
            mPaint.setColor(outerColor);
            canvas.drawRoundRect(outerRectF, outerRadius, outerRadius, mPaint);
            // 绘制内圆(内圆心跟外圆心保持同一个圆心坐标,半径发生变化)
            float size = outerRadius - insideRadius;
            RectF insideRectF = new RectF();
            insideRectF.left = outerRectF.left + size;
            insideRectF.right = outerRectF.right - size;
            insideRectF.top = outerRectF.top + size;
            insideRectF.bottom = outerRectF.bottom - size;
            mPaint.setColor(insideColor);
            canvas.drawRoundRect(insideRectF, outerRadius, outerRadius, mPaint);
        } else {
            // 绘制内圆(圆心不变,半径发生变化)
            RectF rectF = new RectF();
            rectF.left = curDistance;
            rectF.right = insideRadius * 2 - curDistance;
            rectF.top = curDistance;
            rectF.bottom = insideRadius * 2 - curDistance;
            mPaint.setColor(insideColor);
            canvas.drawRoundRect(rectF, insideRadius, insideRadius, mPaint);
        }
    }

    /**
     * 初始化数据
     */
    private void init() {
        isDraw = false;
        isRun = false;
        curDistance = 0;
        delayTime = 0;
        insideRadius = 0;
        outerRadius = 0;
        if (mPaint == null) {
            mPaint = new Paint();
            // 防抖动
            mPaint.setDither(true);
            // 抗锯齿
            mPaint.setAntiAlias(true);
            // 设置绘画的连接
            mPaint.setStrokeJoin(Paint.Join.ROUND);
        }
    }

    /**
     * 开始
     */
    public synchronized void start() {
        if (isRun == false) {
            isRun = true;
            mThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    if (delayTime > 0) {
                        // 如果有延迟显示时间
                        try {
                            Thread.sleep(delayTime);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        delayTime = 0;
                    }
                    isDraw = true;
                    // 如果不想优先显示最大抖动缩放距离,可省略此句
                    curDistance = shakeDistance;
                    while (isRun) {
                        postInvalidate();
                        if (curDistance > 0) {
                            curDistance = 0;
                        } else {
                            curDistance = shakeDistance;
                        }
                        try {
                            Thread.sleep(500);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
            mThread.start();
        }
    }

    /**
     * 停止
     */
    public synchronized void stop() {
        try {
            isRun = false;
            isDraw = false;
            // 如果当前Thread不为空,并且存活,并且还没有被中断
            if (mThread != null && mThread.isAlive() && !mThread.isInterrupted()) {
                mThread.interrupt();
            }
        } catch (Exception ex) {
        } finally {
            mThread = null;
        }
    }

    /**
     * 设置外圆半径
     *
     * @param outerRadius
     */
    public void setOuterRadius(float outerRadius) {
        this.outerRadius = outerRadius;
    }

    /**
     * 设置内圆半径
     *
     * @param insideRadius
     */
    public void setInsideRadius(float insideRadius) {
        this.insideRadius = insideRadius;
    }

    /**
     * 设置圆的抖动(缩放)距离
     *
     * @param shakeDistance
     */
    public void setShakeDistance(float shakeDistance) {
        this.shakeDistance = shakeDistance;
    }

    /**
     * 设置外圆颜色
     *
     * @param outerColor
     */
    public void setOuterColor(int outerColor) {
        this.outerColor = outerColor;
    }

    /**
     * 设置内圆颜色
     *
     * @param insideColor
     */
    public void setInsideColor(int insideColor) {
        this.insideColor = insideColor;
    }

    /**
     * 设置延迟显示时间
     *
     * @param delayTime
     */
    public void setDelayTime(long delayTime) {
        this.delayTime = delayTime;
    }

}

效果图 :    

关于文中所取的px值,详情参见android分辨率适配

猜你喜欢

转载自blog.csdn.net/u011038298/article/details/84786307