Android中圆形进度条的应用还是挺多的,最近学习实现了圆形进度条。

bcc3addeb737

RingProgressBar

bcc3addeb737

meizu style

思路

要实现圆形进度条,

首先要画灰色背景圆环

再画蓝色进度圆环

再画进度数字

搞定。

首先自定义各种属性

初始化各种属性

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RingProgressBar);

ringColor = typedArray.getColor(R.styleable.RingProgressBar_ringColor, Color.GRAY);

ringProgressColor = typedArray.getColor(R.styleable.RingProgressBar_ringProgressColor, Color.GREEN);

textColor = typedArray.getColor(R.styleable.RingProgressBar_textColor, Color.GREEN);

textSize = typedArray.getDimension(R.styleable.RingProgressBar_textSize, 16);

ringWidth = typedArray.getDimension(R.styleable.RingProgressBar_ringWidth, 5);

max = typedArray.getInteger(R.styleable.RingProgressBar_max, 100);

textIsDisplayable = typedArray.getBoolean(R.styleable.RingProgressBar_showTextProgress, true);

style = typedArray.getInt(R.styleable.RingProgressBar_style, 0);

//资源回收

typedArray.recycle();

初始化三种画笔

//背景圆环画笔

ringPaint = new Paint();

ringPaint.setColor(ringColor);

ringPaint.setStyle(Paint.Style.STROKE);

ringPaint.setStrokeWidth(ringWidth);

ringPaint.setAntiAlias(true);

//进度圆环画笔

ringProgressPaint = new Paint();

ringProgressPaint.setColor(ringProgressColor);

ringProgressPaint.setStrokeWidth(ringWidth);

ringProgressPaint.setStrokeCap(Paint.Cap.ROUND);

ringProgressPaint.setAntiAlias(true);

switch (style) {

case STROKE:

ringProgressPaint.setStyle(Paint.Style.STROKE);

break;

case FULL:

ringProgressPaint.setStyle(Paint.Style.FILL_AND_STROKE);

break;

}

//进度文字画笔

textPaint = new Paint();

textPaint.setColor(textColor);

textPaint.setTextSize(textSize);

textPaint.setTypeface(Typeface.DEFAULT_BOLD);

抗锯齿

ringPaint.setAntiAlias(true);

圆形线条

ringProgressPaint.setStrokeCap(Paint.Cap.ROUND);

圆环整体图

bcc3addeb737

圆环整体图

画背景圆环

int xCenter = getWidth() / 2;

int yCenter = getHeight() / 2;

int radius = (int) (xCenter - ringWidth / 2);

canvas.drawCircle(xCenter, yCenter, radius, ringPaint);

xCenter:圆心横坐标

yCenter:圆心纵坐标

radius:半径

ringPaint:画笔

疑惑

这里我有点疑惑,为什么半径是xCenter - ringWidth / 2呢?

我认为半径应该是xCenter - ringWidth才对,很合理,宽度的一半减去线条宽度,刚好是圆环的半径。

怀着疑惑的心情画了上图,这里减去圆环线条宽度的一半或许是因为线条的宽度不可忽略,姑且这样认为吧,如果有大神看到希望指点迷津。

画进度圆环

RectF rectF = new RectF(xCenter - radius, yCenter - radius, xCenter + radius, yCenter + radius);

switch (style) {

case STROKE:

/*canvas.drawArc(rectF, 90, progress * 180 / max, false, ringProgressPaint);

canvas.drawArc(rectF, 90, -progress * 180 / max, false, ringProgressPaint);*/

canvas.drawArc(rectF, -90, progress * 360 / max, false, ringProgressPaint);

break;

case FULL:

if (progress != 0) {

canvas.drawArc(rectF, -90, progress * 360 / 100, true, ringProgressPaint);

}

break;

}

左上右下

RectF rectF = new RectF(xCenter - radius, yCenter - radius, xCenter + radius, yCenter + radius);

xCenter - radius:矩形距离左边的距离

yCenter - radius:矩形距离上边的距离

xCenter + radius:矩形距离右边的距离

yCenter + radius:矩形距离下边的距离

其实可以理解为矩形左上角的坐标和右下角的坐标

画圆弧

canvas.drawArc(rectF, -90, progress * 360 / max, false, ringProgressPaint);

rectF:圆弧在这个矩形中绘制

-90:圆弧顺时针绘制的开始角度

progress * 360 / max:圆弧绘制的角度

false:绘制时是否经过圆心,当style设置为STROKE时,是没有效果的,这里借用两张图片,简单明了

当style设置为FULL,这里设置为false时

bcc3addeb737

false

当style设置为FULL,这里设置为true时

bcc3addeb737

true

ringProgressPaint:画笔

魅族应用市场下载效果

bcc3addeb737

meizu

canvas.drawArc(rectF, 90, progress * 180 / max, false, ringProgressPaint);

canvas.drawArc(rectF, 90, -progress * 180 / max, false, ringProgressPaint);

将进度分两次绘制,从底部同时向上绘制进度的一半,就达到了这个效果。

画进度数字

String text = progress + "%";

float textWidth = textPaint.measureText(text, 0, text.length());

if (showTextProgress && progress != 0 && style == STROKE) {

canvas.drawText(text, xCenter - textWidth / 2, yCenter + textSize / 2, textPaint);

}

RingProgressBar

package com.goldou.ringprogressbar;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.RectF;

import android.graphics.Typeface;

import android.support.annotation.Nullable;

import android.util.AttributeSet;

import android.view.View;

/**

* Created by Administrator on 2017.10.30 0030.

*/

public class RingProgressBar extends View {

private Paint ringPaint;

private Paint ringProgressPaint;

private Paint textPaint;

private int ringColor;

private int ringProgressColor;

private int textColor;

private float textSize;

private float ringWidth;

private int max;

private int progress;

private boolean showTextProgress;

private int style;

private final int STROKE = 0;

private final int FULL = 1;

private Context context;

public RingProgressBar(Context context) {

this(context, null);

}

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

this(context, attrs, 0);

}

public RingProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

this.context = context;

initAttrs(context, attrs);

initPaint();

}

private void initPaint() {

ringPaint = new Paint();

ringPaint.setColor(ringColor);

ringPaint.setStyle(Paint.Style.STROKE);

ringPaint.setStrokeWidth(ringWidth);

ringPaint.setAntiAlias(true);

ringProgressPaint = new Paint();

ringProgressPaint.setColor(ringProgressColor);

ringProgressPaint.setStrokeWidth(ringWidth);

ringProgressPaint.setStrokeCap(Paint.Cap.ROUND);

ringProgressPaint.setAntiAlias(true);

switch (style) {

case STROKE:

ringProgressPaint.setStyle(Paint.Style.STROKE);

break;

case FULL:

ringProgressPaint.setStyle(Paint.Style.FILL_AND_STROKE);

break;

}

textPaint = new Paint();

textPaint.setColor(textColor);

textPaint.setTextSize(textSize);

textPaint.setTypeface(Typeface.DEFAULT_BOLD);

}

private void initAttrs(Context context, AttributeSet attrs) {

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RingProgressBar);

ringColor = typedArray.getColor(R.styleable.RingProgressBar_ringColor, Color.GRAY);

ringProgressColor = typedArray.getColor(R.styleable.RingProgressBar_ringProgressColor, Color.GREEN);

textColor = typedArray.getColor(R.styleable.RingProgressBar_textColor, Color.GREEN);

textSize = typedArray.getDimension(R.styleable.RingProgressBar_textSize, 16);

ringWidth = typedArray.getDimension(R.styleable.RingProgressBar_ringWidth, 5);

max = typedArray.getInteger(R.styleable.RingProgressBar_max, 100);

showTextProgress = typedArray.getBoolean(R.styleable.RingProgressBar_showTextProgress, true);

style = typedArray.getInt(R.styleable.RingProgressBar_style, 0);

//资源回收

typedArray.recycle();

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

int xCenter = getWidth() / 2;

int yCenter = getHeight() / 2;

int radius = (int) (xCenter - ringWidth / 2);

canvas.drawCircle(xCenter, yCenter, radius, ringPaint);

RectF rectF = new RectF(xCenter - radius, yCenter - radius, xCenter + radius, yCenter + radius);

switch (style) {

case STROKE:

/*canvas.drawArc(rectF, 90, progress * 180 / max, false, ringProgressPaint);

canvas.drawArc(rectF, 90, -progress * 180 / max, false, ringProgressPaint);*/

canvas.drawArc(rectF, -90, progress * 360 / max, false, ringProgressPaint);

break;

case FULL:

if (progress != 0) {

canvas.drawArc(rectF, -90, progress * 360 / 100, true, ringProgressPaint);

}

break;

}

String text = progress + "%";

float textWidth = textPaint.measureText(text, 0, text.length());

if (showTextProgress && progress != 0 && style == STROKE) {

canvas.drawText(text, xCenter - textWidth / 2, yCenter + textSize / 2, textPaint);

}

}

public synchronized int getMax() {

return max;

}

public synchronized void setMax(int max) {

if (max < 0) {

throw new IllegalArgumentException("max not less than 0");

}

this.max = max;

}

public synchronized int getProgress() {

return progress;

}

public synchronized void setProgress(int progress) {

if (progress < 0) {

throw new IllegalArgumentException("progress not less than 0");

}

if (progress > max) {

progress = max;

}

if (progress <= max) {

this.progress = progress;

postInvalidate();

}

}

public int getRingColor() {

return ringColor;

}

public void setRingColor(int ringColor) {

this.ringColor = ringColor;

}

public int getRingProgressColor() {

return ringProgressColor;

}

public void setRingProgressColor(int ringProgressColor) {

this.ringProgressColor = ringProgressColor;

}

public int getTextColor() {

return textColor;

}

public void setTextColor(int textColor) {

this.textColor = textColor;

}

public float getTextSize() {

return textSize;

}

public void setTextSize(float textSize) {

this.textSize = textSize;

}

public float getRingWidth() {

return ringWidth;

}

public void setRingWidth(float roundWidth) {

this.ringWidth = roundWidth;

}

}

最后

有什么解释不对还望各位大神指正

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐