请问:怎么可以把代码格式调整?我贴出来换格式了。你们直接去Github下载源码!
动画描述:
主要分3个小块: 发射器, 气泡, 圆环
思路:
一.充电座(完全不透明):
位于屏幕最下方, 取圆弧上的3点, 用3阶贝塞尔曲线构成path
二.气泡(不完全透明):
1.发射器处随机产生气泡;
2.气泡未离开发射器的部分会被发射器遮挡;
3.气泡刚离开发射器,会有一个黏性的变化效果, 使用3阶贝塞尔曲线,将多个变化的点连接起来,构成path;
4.气泡在往上移动中,半径会变小, 小于一定值,气泡会消失;
5.气泡靠近圆环到一定距离,也会有一个黏性变化效果,并且速度变慢, 使用方式类似于3
6.气泡与圆环的零距离时,气泡消失
三.圆环(不完全透明):
1.由多个长度不一的片段构成, 圆弧上的3个点构成一个片段,采用的也是3阶贝塞尔曲线;
2.每个片段都围绕圆环中心旋转,透明度在某个区间不断变化; 旋转速度在某几个值之间也不断改变,从而影响片段之间的开口大小
3.如果手机电量发生改变,显示的电量百分比也发生改变;拖动进度条可改变电量百分比和 发射器,气泡,圆环的颜色
动画分析:重点:黏性效果,怎么判断他们重叠了!!
1.从底下冒泡
2.气泡靠近圆环到一定距离,也会有一个黏性变化效果(通过path.得到闭合的路径)
3.气泡与圆环的零距离时,气泡消失
用到的知识!!
封装控件(特别好的封装思想)
1.每一个控件单独出来.不一定要继承view.可以传入一个canvas过来
/**
* 绘制发射器
*/
public void drawEmitter(Canvas canvas, Paint paint) {//缺少cavas,传入了一个canvas
paint.setColor(color);
canvas.drawPath(mPath, paint);
}
2.控件设置属性,用构造者模式
3.view的宽高
getViewTreeObserver().addOnGlobalLayoutListener
4.半圆弧的绘制
发射器的3个点,用来连接成弧线
canvas.drawPath(mPath, paint)
path.cubicTo(c[0].x, c[0].y, c[1].x, c[1].y, points[i].x, points[i].y);
5.圆弧是怎么画出来的?
通过path: canvas.drawPath(mDynamicPath, paint)
6.速度的控制可用插值器,不用自己计算
public class BubbleEmitter {
/*** path系数 */
private float lineSmoothness;
/*** 发射器颜色 */
private int color;
/*** 发射器的3个点,用来连接成弧线 */
private PointF[]mPoints =new PointF[3];
/*** 发射器路径 */
private PathmPath =new Path();
public BubbleEmitter(EmitterBuilder builder) {
if (builder.lineSmoothness <=0)throw new IllegalArgumentException("lineSmoothness <= 0");
this.lineSmoothness = builder.lineSmoothness;
this.color = builder.color;
}
static class EmitterBuilderextends Builder {
@Override
public BubbleEmitterbuild() {
return new BubbleEmitter(this);
}
}
/**
* 生成点集合,并连接在一起
*/
public void generatePoints(float emitterCenterX, float emitterCenterY, float emitterRadius,
float startAngle, float sweepAngle) {
mPoints = ChargingHelper.generatePoints(emitterCenterX, emitterCenterY,
emitterRadius, startAngle, sweepAngle);
//连接路径
ChargingHelper.connectToPath(mPath, mPoints, lineSmoothness);
}
/**
* 设置颜色
*
* @param color
*/
public void setColor(int color) {
this.color = color;
}
/**
* 绘制发射器
*/
public void drawEmitter(Canvas canvas, Paint paint) {//缺少cavas,传入了一个canvas
paint.setColor(color);
canvas.drawPath(mPath, paint);
}
}
public class BubbleController {
private StringTAG ="BubbleController";
private Randomrd;
/*** path系数 */
private float lineSmoothness;
/*** 气泡的最小半径 */
private float minBubbleRadius;
/*** 气泡的最大半径 */
private float maxBubbleRadius;
/*** 速率百分比,当气泡与发射器之间有粘合贝塞尔曲线时,运动速度减慢 */
private float speedRadio;
/*** 半径变化率 */
private float radiusRadio;
/*** 气泡的最小速度 */
private float minBubbleSpeedY;
/*** 气泡的最大速度 */
private float maxBubbleSpeedY;
/*** 气泡最多有几个 */
private int maxBubbleCount;
/*** 气泡颜色 */
private int color;
/*** 圆环中心坐标 */
private int circularCenterX, circularCenterY;
/*** 圆环半径 */
private float circularRadius;
/*** 发射器的中心x坐标 */
private float emitterCenterX;
/*** 发射器的中心y坐标 */
private double emitterCenterY;
/*** 发射器半径 */
private float emitterRadius;
/*** 气泡集合 */
public ListmBubbleList =new ArrayList<>();
/*** 气泡关于路径的map */
private MapmBubblePathMap =new HashMap<>();
//气泡与圆环黏和的点数组
private PointF[]bubblePoints =new PointF[7];
/*** 和固定控制点有关的常量 */
private static final float C =0.551915024494f;
public BubbleController(BubbleControllerBuilder builder) {
if (builder.rd ==null)throw new NullPointerException("builder.rd == null");
if (builder.lineSmoothness <=0)throw new IllegalArgumentException("lineSmoothness <= 0");
if (builder.maxBubbleRadius <= builder.minBubbleRadius)
throw new IllegalArgumentException("builder.maxBubbleRadius <= builder.minBubbleRadius");
if (builder.maxBubbleSpeedY <= builder.minBubbleSpeedY)
throw new IllegalArgumentException("builder.maxBubbleSpeedY <= builder.minBubbleSpeedY");
this.rd = builder.rd;
this.lineSmoothness = builder.lineSmoothness;
this.minBubbleRadius = builder.minBubbleRadius;
this.maxBubbleRadius = builder.maxBubbleRadius;
this.speedRadio = builder.speedRadio;
this.radiusRadio = builder.radiusRadio;
this.minBubbleSpeedY = builder.minBubbleSpeedY;
this.maxBubbleSpeedY = builder.maxBubbleSpeedY;
this.maxBubbleCount = builder.maxBubbleCount;
this.color = builder.color;
this.circularCenterX = builder.circularCenterX;
this.circularCenterY = builder.circularCenterY;
this.circularRadius = builder.circularRadius;
this.emitterCenterX = builder.emitterCenterX;
this.emitterCenterY = builder.emitterCenterY;
this.emitterRadius = builder.emitterRadius;
for (int i =0; i
bubblePoints[i] =new PointF();
}
}
static class BubbleControllerBuilderextends Builder {
private Randomrd;
/*** 气泡的最小半径 */
private float minBubbleRadius;
/*** 气泡的最大半径 */
private float maxBubbleRadius;
/*** 速率百分比,当气泡与发射器之间有粘合贝塞尔曲线时,运动速度减慢 */
private float speedRadio;
/*** 半径变化率 */
private float radiusRadio;
/*** 气泡的最小速度 */
private float minBubbleSpeedY;
/*** 气泡的最大速度 */
private float maxBubbleSpeedY;
/*** 气泡最多有几个 */
private int maxBubbleCount;
/*** 圆环中心坐标 */
private int circularCenterX, circularCenterY;
/*** 圆环半径 */
private float circularRadius;
/*** 发射器的中心x坐标 */
private float emitterCenterX;
/*** 发射器的中心y坐标 */
private double emitterCenterY;
/*** 发射器半径 */
private float emitterRadius;
public BubbleControllerBuildersetMinBubbleRadius(float minBubbleRadius) {
this.minBubbleRadius = minBubbleRadius;
return this;
}
public BubbleControllerBuildersetMaxBubbleRadius(float maxBubbleRadius) {
this.maxBubbleRadius = maxBubbleRadius;
return this;
}
public BubbleControllerBuildersetSpeedRadio(float speedRadio) {
this.speedRadio = speedRadio;
return this;
}
public BubbleControllerBuildersetRadiusRadio(float radiusRadio) {
this.radiusRadio = radiusRadio;
return this;
}
public BubbleControllerBuildersetMinBubbleSpeedY(float minBubbleSpeedY) {
this.minBubbleSpeedY = minBubbleSpeedY;
return this;
}
public BubbleControllerBuildersetMaxBubbleSpeedY(float maxBubbleSpeedY) {
this.maxBubbleSpeedY = maxBubbleSpeedY;
return this;
}
public BubbleControllerBuildersetMaxBubbleCount(int maxBubbleCount) {
this.maxBubbleCount = maxBubbleCount;
return this;
}
public BubbleControllerBuildersetRd(Random rd) {
this.rd = rd;
return this;
}
public BubbleControllerBuildersetCircularCenterX(int circularCenterX) {
this.circularCenterX = circularCenterX;
return this;
}
public BubbleControllerBuildersetCircularCenterY(int circularCenterY) {
this.circularCenterY = circularCenterY;
return this;
}
public BubbleControllerBuildersetCircularRadius(float circularRadius) {
this.circularRadius = circularRadius;
return this;
}
public BubbleControllerBuildersetEmitterCenterX(float emitterCenterX) {
this.emitterCenterX = emitterCenterX;
return this;
}
public BubbleControllerBuildersetEmitterCenterY(double emitterCenterY) {
this.emitterCenterY = emitterCenterY;
return this;
}
public BubbleControllerBuildersetEmitterRadius(float emitterRadius) {
this.emitterRadius = emitterRadius;
return this;
}
@Override
public BubbleControllerbuild() {
return new BubbleController(this);
}
}
/**
* 生成气泡
*/
public void generateBubble() {
if (mBubbleList.size() >=maxBubbleCount)return;
//延迟生成气泡的作用
if (rd.nextBoolean() ||rd.nextBoolean() ||rd.nextBoolean())return;
int bubbleAlpha =255 /2 +rd.nextInt(255 /2);
float radius =minBubbleRadius +rd.nextInt((int) (maxBubbleRadius -minBubbleRadius));
//气泡的x起始坐标
float x =circularCenterX -emitterRadius + radius +rd.nextInt((int) (2 * (emitterRadius - radius)));
//气泡的y起始坐标
float y =circularCenterY *2 + radius;
//气泡的起始速度
float speedY =minBubbleSpeedY +rd.nextFloat() * (maxBubbleSpeedY -minBubbleSpeedY);
float sizeRadio =radiusRadio *rd.nextFloat();
ChargingHelper.generateBubble(mBubbleList, x, y, radius, speedY, bubbleAlpha, color, sizeRadio);
}
/**
* 遍历气泡
*/
public void performTraversals() {
for (int i =0; i
Bubble b =mBubbleList.get(i);
if (b.getRadius()
mBubbleList.remove(b);
if (mBubblePathMap.containsKey(b)) {
mBubblePathMap.remove(b);
}
i--;
continue;
}
b.setY(b.getY() - b.getSpeedY());
if (!b.isUnAccessible()) {
//改变半径
b.setRadius(b.getRadius() - b.getSizeRadio());
}
changeBubblePath(b);
}
}
/**
* 改变气泡的路径
*
* @param b
*/
private void changeBubblePath(Bubble b) {
Path path =mBubblePathMap.get(b);
if (path ==null) {
path =new Path();
mBubblePathMap.put(b, path);
}else {
path.reset();
}
//气泡圆心和发射器圆心距离
double beDistance = getCenterDistance(b.getX(), b.getY(), emitterCenterX, (float)emitterCenterY);
//气泡圆心和圆环中心距离
double bcDistance = getCenterDistance(b.getX(), b.getY(), circularCenterX, circularCenterY);
generatePath(b, path, beDistance, bcDistance);
}
private void generatePath(Bubble b, Path path, double beDistance, double bcDistance) {
path.addCircle(b.getX(), b.getY(), b.getRadius(), Path.Direction.CCW);
//气泡的界限
if (bcDistance >=circularRadius + b.getRadius() && bcDistance
//判断是否有粘性
if (b.getRadius() >=minBubbleRadius) {
//圆环-气泡半径方向的偏移
float offset = b.getRadius();
//偏移的距离
float offsetDistance = b.getRadius();
if (b.getSpeedY() >minBubbleSpeedY) {
b.setSpeedY(b.getSpeedY() *speedRadio);
}
//获取弧度
double rad = DegreeUtil.getCoordinateRadians(circularCenterX - b.getX(), circularCenterY - b.getY());
//得到角度
double degree = DegreeUtil.toDegrees(rad);
//y方向上的偏移量
double yOffset = DegreeUtil.getSinSideLength(offset, rad);
//这段偏移会耗费的时长
double t = yOffset / b.getSpeedY();
//运行多久了
double d =circularRadius + b.getRadius() + offset - bcDistance;
//y方向上运行了多长距离
double yd = DegreeUtil.getSinSideLength(d, rad);
//已经消耗的时间
double ht = yd * t / yOffset;
bubblePoints[3].x = (float) (circularCenterX + DegreeUtil.getCosSideLength(circularRadius, rad));
bubblePoints[3].y = (float) (circularCenterY + DegreeUtil.getSinSideLength(circularRadius, rad));
//左右两侧的点
float sinSideLen = (float) (b.getRadius() + ht * offsetDistance / t);
double cosSideLen = Math.sqrt(Math.pow(circularRadius, 2) - Math.pow(sinSideLen, 2));
PointF[] p2 = ChargingHelper.generatePoints(circularCenterX, circularCenterY, degree, cosSideLen, sinSideLen, true);
bubblePoints[2] = p2[0];
bubblePoints[4] = p2[1];
//对边长度
float sinSideLength2 = (float) (b.getRadius() /2 + ht * b.getRadius() / (2 * t));
//邻边长度
double cosSideLength2 = Math.sqrt(Math.pow(b.getRadius(), 2) - Math.pow(sinSideLength2, 2));
//直角边长度
double cosSideLength3 = bcDistance - cosSideLength2;
PointF[] p3 = ChargingHelper.generatePoints(circularCenterX, circularCenterY, degree, cosSideLength3, sinSideLength2, true);
bubblePoints[0] = p3[0];
bubblePoints[6] = p3[1];
//邻边长度
double cosSideLength4 =circularRadius + (bcDistance -circularRadius - b.getRadius()) *C;
//对角边长度
double sinSideLength4 = sinSideLen *C;
PointF[] p4 = ChargingHelper.generatePoints(circularCenterX, circularCenterY, degree, cosSideLength4, sinSideLength4, true);
bubblePoints[1] = p4[0];
bubblePoints[5] = p4[1];
ChargingHelper.connectToPath(path, bubblePoints, lineSmoothness);
//半径不再变
b.setUnAccessible(true);
}
}else if (beDistance >=emitterRadius + b.getRadius() && beDistance
//发射器-气泡半径方向的偏移
float offset = b.getRadius() /2;
float offsetDistance = b.getRadius() /3;
if (b.getSpeedY() > (minBubbleSpeedY +maxBubbleSpeedY) /2) {
b.setSpeedY(b.getSpeedY() * (1 -speedRadio *speedRadio));
}
//获取弧度
double rad = DegreeUtil.getCoordinateRadians2(emitterCenterX - b.getX(), emitterCenterY - b.getY());
//得到角度
double degree = DegreeUtil.toDegrees(rad);
//y方向上的偏移量
double yOffset = DegreeUtil.getSinSideLength(offset, rad);
//这段偏移会耗费的时长
double t = yOffset / b.getSpeedY();
//运行多久了
double d = beDistance -emitterRadius - b.getRadius();
//y方向上运行了多长距离
double yd = DegreeUtil.getSinSideLength(d, rad);
//已经消耗的时间
double ht = yd * t / yOffset;
bubblePoints[3].x = (float) (emitterCenterX + DegreeUtil.getCosSideLength(emitterRadius, rad));
bubblePoints[3].y = (float) (emitterCenterY - DegreeUtil.getSinSideLength(emitterRadius, rad));
//左右两侧的点
double sinSideLen = b.getRadius() - ht * offsetDistance / t;
double cosSideLen = Math.sqrt(Math.pow(emitterRadius, 2) - Math.pow(sinSideLen, 2));
PointF[] p2 = ChargingHelper.generatePoints(emitterCenterX, (float)emitterCenterY, degree, cosSideLen, sinSideLen, false);
bubblePoints[4] = p2[0];
bubblePoints[2] = p2[1];
//对边长度
float sinSideLength2 = (float) (b.getRadius() - ht * b.getRadius() / (2 * t));
//邻边长度
double cosSideLength2 = Math.sqrt(Math.pow(b.getRadius(), 2) - Math.pow(sinSideLength2, 2));
//直角边长度
double cosSideLength3 = beDistance - cosSideLength2;
PointF[] p3 = ChargingHelper.generatePoints(emitterCenterX, (float)emitterCenterY, degree, cosSideLength3, sinSideLength2, false);
bubblePoints[6] = p3[0];
bubblePoints[0] = p3[1];
//邻边长度
double cosSideLength4 =emitterRadius + (beDistance -emitterRadius - b.getRadius()) *C;
//对角边长度
double sinSideLength4 = sinSideLen *C;
PointF[] p4 = ChargingHelper.generatePoints(emitterCenterX, (float)emitterCenterY, degree, cosSideLength4, sinSideLength4, false);
bubblePoints[5] = p4[0];
bubblePoints[1] = p4[1];
ChargingHelper.connectToPath(path, bubblePoints, lineSmoothness);
}else {
b.setSpeedY(b.getOriginalSpeedY());
}
}
/**
* 获取气泡中心和发射器中心的距离平方
*
* @return
*/
private double getCenterDistance(float x1, float y1, float x2, float y2) {
PointF p1 =new PointF(x1, y1);
PointF p2 =new PointF(x2, y2);
return GeometryUtil.getDistanceBetween2Points(p1, p2);
}
/**
* 修改颜色
*
* @param color
*/
public void setColor(int color) {
this.color = color;
mBubblePathMap.clear();
mBubbleList.clear();
}
/**
* 绘制气泡
*
* @param canvas
*/
public void drawBubble(Canvas canvas, Paint paint) {
for (int i =0; i
Bubble b =mBubbleList.get(i);
paint.setColor(b.getColor());
Path path =mBubblePathMap.get(b);
if (path !=null) {
canvas.drawPath(path, paint);
}
}
}
/**
* 是否碰撞到量圆环,如果碰撞到了,则气泡消失
*
* @param b
* @return
*/
private boolean hitCircular(Bubble b) {
return getCenterDistance(circularCenterX,
circularCenterY, b.getX(), b.getY()) <=circularRadius + b.getRadius();
}
}
public class CircularSegments {
private StringTAG ="CircularSegments";
/*** 圆环片段集合 */
private ListmSegments =new ArrayList<>();
private Randomrd;
/*** 偏移的最大值 */
private float maxOffset;
/*** 偏移量最小值 */
private float minOffset;
/*** 总的旋转角度差 最大值 */
private float maxDValueAngle;
/*** 正常的旋转速率 */
private float rotateRadio;
/*** path系数 */
private float lineSmoothness;
/*** 最小的角度 */
private int minAngle;
/*** 偏移增大率 */
private float offsetRadio;
/*** 旋转速率的差值 */
private float radio_dVal;
/*** 颜色 */
private int color;
/*** 圆环片段数量 */
private int segmentCount;
/*** 圆心 */
private int circularCenterX, circularCenterY;
/*** 圆环半径 */
private float circularRadius;
public CircularSegments(CircularSegmentsBuilder builder) {
if (builder.rd ==null)throw new NullPointerException("builder.rd == null");
if (builder.lineSmoothness <=0)throw new IllegalArgumentException("lineSmoothness <= 0");
if (builder.minOffset > builder.maxOffset)
throw new IllegalArgumentException("builder.minOffset > builder.maxOffset");
if (builder.segmentCount <=0)
throw new IllegalArgumentException("builder.segmentCount <= 0");
this.rd = builder.rd;
this.lineSmoothness = builder.lineSmoothness;
this.color = builder.color;
this.minAngle = builder.minAngle;
this.offsetRadio = builder.offsetRadio;
this.radio_dVal = builder.radio_dVal;
this.rotateRadio = builder.rotateRadio;
this.maxDValueAngle = builder.maxDValueAngle;
this.minOffset = builder.minOffset;
this.maxOffset = builder.maxOffset;
this.segmentCount = builder.segmentCount;
this.circularCenterX = builder.circularCenterX;
this.circularCenterY = builder.circularCenterY;
this.circularRadius = builder.circularRadius;
}
static class CircularSegmentsBuilderextends Builder {
/*** 随机Random */
private Randomrd;
/*** 圆环片段最小角度 */
private int minAngle;
/*** 偏移增大率 */
private float offsetRadio;
/*** 旋转速率的差值 */
private float radio_dVal;
/*** 正常的旋转速率 */
private float rotateRadio;
/*** 总的旋转角度差 最大值 */
private float maxDValueAngle;
/*** 偏移的最大值 */
private float maxOffset;
/*** 偏移量最小值 */
private float minOffset;
/*** 圆环片段数量 */
private int segmentCount;
/*** 圆心 */
private int circularCenterX, circularCenterY;
/*** 圆环半径 */
private float circularRadius;
public CircularSegmentsBuildersetRd(Random rd) {
this.rd = rd;
return this;
}
public CircularSegmentsBuildersetMinAngle(int minAngle) {
this.minAngle = minAngle;
return this;
}
public CircularSegmentsBuildersetOffsetRadio(float offsetRadio) {
this.offsetRadio = offsetRadio;
return this;
}
public CircularSegmentsBuildersetRadio_dVal(float radio_dVal) {
this.radio_dVal = radio_dVal;
return this;
}
public CircularSegmentsBuildersetRotateRadio(float rotateRadio) {
this.rotateRadio = rotateRadio;
return this;
}
public CircularSegmentsBuildersetMaxDValueAngle(float maxDValueAngle) {
this.maxDValueAngle = maxDValueAngle;
return this;
}
public CircularSegmentsBuildersetMaxOffset(float maxOffset) {
this.maxOffset = maxOffset;
return this;
}
public CircularSegmentsBuildersetMinOffset(float minOffset) {
this.minOffset = minOffset;
return this;
}
public CircularSegmentsBuildersetSegmentCount(int segmentCount) {
this.segmentCount = segmentCount;
return this;
}
public CircularSegmentsBuildersetCircularCenterX(int circularCenterX) {
this.circularCenterX = circularCenterX;
return this;
}
public CircularSegmentsBuildersetCircularCenterY(int circularCenterY) {
this.circularCenterY = circularCenterY;
return this;
}
public CircularSegmentsBuildersetCircularRadius(float circularRadius) {
this.circularRadius = circularRadius;
return this;
}
@Override
public CircularSegmentsbuild() {
return new CircularSegments(this);
}
}
/**
* 生成一个圆环
*/
public void generateCircular() {
//角度数组
float[] sweepAngleArr =new float[segmentCount];
float startAngle =0;
int averageAngle =360 /segmentCount;
//扫描角度的偏移量
int offsetAngle =0;
for (int i =0; i < sweepAngleArr.length; i++) {
offsetAngle =rd.nextInt(segmentCount);
if (i != sweepAngleArr.length -1) {
sweepAngleArr[i] =minAngle +rd.nextInt(Math.abs(averageAngle -minAngle)) + offsetAngle;
}else {
//剩余的扫描角度赋值给最后一个圆环片段
sweepAngleArr[i] =360 - startAngle + offsetAngle;
}
//透明度
int alphaRadio =rd.nextInt(segmentCount);
int maxAlpha =255 /2 +rd.nextInt(255 / (segmentCount /2));
int minAlpha = maxAlpha -rd.nextInt(255 /segmentCount );
int quickRotateStartAngle =rd.nextInt(360);
float offsetMax =minOffset +rd.nextInt((int) (maxOffset -minOffset));
CircularSeg seg =new CircularSeg.CircularSegBuilder()
.setColor(color)
.setAlphaRadio(alphaRadio)
.setMinAlpha(minAlpha)
.setMaxAlpha(maxAlpha)
.setQuickRotateStartAngle(quickRotateStartAngle)
.setOffsetMax(offsetMax)
.setRadio_dVal(radio_dVal)
.setMaxDValueAngle(maxDValueAngle)
.setRotateRadio(rotateRadio)
.setOffsetRadio(offsetRadio)
.setLineSmoothness(lineSmoothness)
.build();
seg.generatePoints(circularCenterX, circularCenterY, circularRadius, startAngle, sweepAngleArr[i]);
mSegments.add(seg);
startAngle += sweepAngleArr[i] - offsetAngle;
}
}
/**
* 改变圆环的路径
*/
public void changeCircular() {
for (int i =0; i
CircularSeg seg =mSegments.get(i);
seg.changePath();
seg.changeAlpha();
}
}
/**
* 改变颜色
*
* @param color
*/
public void setColor(int color) {
for (int i =0; i
CircularSeg seg =mSegments.get(i);
seg.setColor(color);
}
}
/**
* 绘制圆环
*/
public void drawSegments(Canvas canvas, Paint paint) {
for (int i =0; i
CircularSeg seg =mSegments.get(i);
seg.drawSegment(canvas, paint);
}
}
}
参考博客:
https://www.jianshu.com/p/20fec8dba5b5
https://blog.csdn.net/qq_40446718/article/details/83445363