android数据球图,Android 绘制水波纹小球球

ba5912075fb9

1615521127828.gif

public class BezierCurvePercentView extends View {

//外圈

private Paint paintOutside;

private int paintOutsideColor = Color.parseColor("#FD6F5C");

//背景色

private Paint paintBg;

private int paintBgColor = Color.parseColor("#F4F4F4");

//已使用百分比

private Paint paintPercent;

private int paintPercentColor = Color.parseColor("#FD6F5C");

private Path percentPath;

//文本

private Paint paintText;

private int paintTextColor = Color.parseColor("#ffffff");

private float percent = 0.3f;

/**

* 波纹的长度

*/

private int WAVE_LENGTH = 300;

/**

* 波纹的高度

*/

private final static int WAVE_HEGHT = 20;

private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);

private int viewWidth;

private int viewHeight;

private int dx;

public BezierCurvePercentView(Context context) {

super(context);

}

public BezierCurvePercentView(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

paintOutside = new Paint();

paintOutside.setAntiAlias(true);

paintOutside.setColor(paintOutsideColor);

paintOutside.setStrokeWidth(3f);

paintOutside.setStyle(Paint.Style.STROKE);

paintBg = new Paint();

paintBg.setAntiAlias(true);

paintBg.setColor(paintBgColor);

paintBg.setStyle(Paint.Style.FILL);

paintPercent = new Paint();

paintPercent.setAntiAlias(true);

paintPercent.setColor(paintPercentColor);

paintPercent.setStyle(Paint.Style.FILL);

percentPath = new Path();

paintText = new Paint();

paintText.setAntiAlias(true);

paintText.setColor(paintTextColor);

paintText.setStrokeWidth(2f);

paintText.setTextSize(100);

paintText.setStyle(Paint.Style.FILL);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

viewWidth = MeasureSpec.getSize(widthMeasureSpec);

viewHeight = MeasureSpec.getSize(heightMeasureSpec);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

int layerId = canvas.saveLayer(0, 0, viewWidth, viewHeight, null, Canvas.ALL_SAVE_FLAG);

canvas.drawCircle(viewWidth/2, viewHeight/2, viewWidth/2-2, paintOutside);

canvas.drawCircle(viewWidth/2, viewHeight/2, viewWidth/2-3, paintBg);

percentPath.reset();

percentPath.moveTo( -WAVE_LENGTH + dx, (1-percent)*viewHeight);

for (int i = -WAVE_LENGTH; i < getWidth() + WAVE_LENGTH; i += WAVE_LENGTH) {

percentPath.rQuadTo(WAVE_LENGTH / 4, -WAVE_HEGHT, WAVE_LENGTH / 2, 0);

percentPath.rQuadTo(WAVE_LENGTH / 4, WAVE_HEGHT, WAVE_LENGTH / 2, 0);

}

percentPath.lineTo(viewWidth, viewHeight);

percentPath.lineTo(0, viewHeight);

percentPath.close();

paintPercent.setXfermode(mMode);

canvas.drawPath(percentPath, paintPercent);

paintPercent.setXfermode(null);

Rect rect = new Rect();

String textStr = (int)(percent*100) + "%";

paintText.getTextBounds(textStr, 0, textStr.length(), rect);

canvas.drawText(textStr, viewWidth/2 - rect.width()/2, viewHeight/2 + rect.height()/2, paintText);

canvas.restoreToCount(layerId);

}

public void setPercent(float percent){

this.percent = percent;

ValueAnimator mValueAnimator = ValueAnimator.ofInt(0, WAVE_LENGTH);

mValueAnimator.setDuration(2000);

mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);

// 动画插值器,也可以使用其他

mValueAnimator.setInterpolator(new LinearInterpolator());

mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

dx = ( int ) animation.getAnimatedValue();

invalidate();

}

});

mValueAnimator.start();

}

}

二阶贝塞尔曲线的两个方法 quadTo 与 rQuadTo

path.moveTo(x, y);

quadTo(x1, y1, x2, y2);

quadTo(x3, y3, x4, y4);

此方法中的每个坐标是相对起点的坐标,即 x1-x = x2-x1 = x3-x2 = x4-x3;

path.moveTo(x, y);

rQuadTo(x1, y1, x2, y2);

rQuadTo(x3, y3, x4, y4);

此方法中的每个坐标是相对上一个点的坐标,假设起点是(0, 0),波长是100,波高度20,则:

path.moveTo(0, 0);

rQuadTo(100/4, 20,100/2, 0);

↓↓↓第二段曲线 (x,y)把上一个点看做(0, 0)即相对上一个点X位移量为1/4波长=100/4,Y减少波高度20

rQuadTo(100/4, -20, 100/2, 0);

完整曲线共5个点,如下图:

path.moveTo(起点x, 起点y);

quadTo(Ax, Ay, Bx, By);

quadTo(Cx, Cy, Dx, Dy);

ba5912075fb9

二阶贝塞尔.jpg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值