<p><br> 本文比较详细的介绍了绘制圆环及圆弧的基础知识,为实现钉钉运动步数打下基础,实现了下面的效果,实现钉钉运动就灰常简单了,本文实现的初步效果如下:</p>
<p>如果想直接看钉钉运动的最终效果,请戳:<a href="https://www.jianshu.com/p/6579a41b5ba5">Android进阶之自定义控件(2)高仿钉钉运动步数实现可动的进度圆环(下)</a></p>
<p><br><img alt="" class="blockcode" height="507" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-9c60e203e605b11ef64469ed3f0094e0" width="315"><br> 1、圆环的绘制<br> 2、绘制背景圆环和进度圆环<br> 3、绘制中间的文字<br> (1)使用drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)绘制圆环:<br><br><img alt="" class="blockcode" height="260" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-fedcbb3b86a1e35dea8ba3fab4f512cd" width="395"><br> </p>
<pre class="blockcode"><code> public class SportStepView extends View {
private Paint mPaint;
//圆环绘制的宽度
private int mRoundWidth = 40;
public SportStepView(Context context) {
this(context, null);
}
public SportStepView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SportStepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//获取宽的模式
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//获取宽的尺寸
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
//对wrap_content这种模式进行处理
if (heightMode == MeasureSpec.AT_MOST) {
heightSize = widthSize;
}
//绘制圆环以宽度为标准,保存丈量结果
setMeasuredDimension(widthSize, heightSize);
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(mRoundWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制圆,设置画笔的Style为Paint.Style.STROKE,则绘制出来的为圆环,否则绘制出来的为圆
//canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2 - mRoundWidth / 2, mPaint);
RectF oval = new RectF(0 , 0, getWidth(), getWidth());
//画圆弧 useCenter:是否显示圆内的横线 下面的绘制0,360的圆弧,也可以实现绘制圆环的效果
canvas.drawArc(oval, 0, 360, false, mPaint);
}
}</code></pre>
<p><br><img alt="" class="blockcode" height="372" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-ffc9d5cd5c0507948bfd462ad963e319" width="262"><br> 会发现显示不全,绘制超出边界了,因为圆的宽度是在当前半径向两边展开的。如下图分析得知,圆所在的矩形区域不是rect(为屏幕的矩形区域),而是real Rect所在的区域:<br><img alt="" class="blockcode" height="383" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-05b47eb515431ce2c5fc8cf7937f5319" width="597"><br> 因此只需要修改如下即可。</p>
<pre class="blockcode"><code>RectF oval = new RectF(0 + mRoundWidth / 2, 0 + mRoundWidth / 2, getWidth() - mRoundWidth / 2, getWidth() - mRoundWidth / 2);
// RectF oval = new RectF(0 , 0, getWidth(), getWidth());
//画圆弧 useCenter:是否显示圆内的横线 下面的绘制0,360的圆弧,也可以实现绘制圆环的效果
canvas.drawArc(oval, 0, 360, false, mPaint);</code></pre>
<p><br> 修改后达到我们的预期效果:</p>
<p><br><img alt="" class="blockcode" height="409" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-286f329c56210e072729db8e14cbe42c" width="267"><br> (2)如果只是绘制上面的圆环效果,还可以使用: canvas.drawCircle()的方式实现,这种方法更简单:</p>
<pre class="blockcode"><code> //绘制圆,设置画笔的Style为Paint.Style.STROKE,则绘制出来的为圆环,否则绘制出来的为圆
//由于圆环本身有宽度,所以半径要减去圆环宽度的一半,不然一部分圆会在view外面。
canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2 - mRoundWidth / 2, mPaint);</code></pre>
<p><br> (3)接下来我们来实现背景圆环+进度圆环的效果了,利用drawCircle绘制背景圆环,drawArc()绘制进度圆环,预期效果如下:<br><br><img alt="" class="blockcode" height="379" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-3ca2153f690411484f4ae485199e70a0" width="273"><br> 这个很简单&#x |
|