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分辨率适配