说在前面的话,利用点空余时间,把以前的都写一遍,毕竟,基础不能忘记。现在已经有了很多轮子可以用,但是基础就是让你怎么更好的使用轮子。好了,不多说。
直接上代码,注释都有的。
贴个效果图先:
接下来就是代码了:
import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.os.Handler; import android.os.Message; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.View; import com.example.myapplication.R; /** * Created by Avater on 2017/12/7. */ public class AvaterProgressCycle extends View { private int mFirstColor = Color.parseColor("#191970");//圆形进度的背景色 private int mSecondColor = Color.parseColor("#006400");//进度的背景颜色 private int mWidth = 40;//圆环的宽度 private int mTextSize = 40;//字体的大小 private int mTextColor = mFirstColor;//字体的颜色 private Paint mPaint = new Paint();//画笔 private float currentvalue;//当前的弧度值(0-360) private int mGoal;//设置的进度目标 public AvaterProgressCycle(Context context) { this(context, null); } public AvaterProgressCycle(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public AvaterProgressCycle(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint.setAntiAlias(true);//画笔设置抗锯齿,否则圆形边缘会锐化,变丑 TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.AvaterProgressCycle);//获取自定义属性的集合 int size = array.getIndexCount(); for (int i = 0; i < size; i++) {//遍历取出对应的值 int attr = array.getIndex(i); switch (attr) { case R.styleable.AvaterProgressCycle_FirstColor: mFirstColor = array.getColor(attr, Color.parseColor("#191970")); break; case R.styleable.AvaterProgressCycle_SecondColor: mSecondColor = array.getColor(attr, Color.parseColor("#006400")); break; case R.styleable.AvaterProgressCycle_TextColor: mTextColor = array.getColor(attr, mFirstColor); break; case R.styleable.AvaterProgressCycle_CircleWidth: mWidth = array.getInteger(attr, 40); break; case R.styleable.AvaterProgressCycle_TextSize: mTextSize = (int) array.getDimension(attr, 30); break; } } array.recycle();//及时回收 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /** * 1画圆 * 2画弧度 * 3画文字 */ CanvasCircle(canvas); CanvasArc(canvas); CanvasText(canvas); } /** * 画文字 * * @param canvas */ private void CanvasText(Canvas canvas) { mPaint.setColor(mTextColor);//设置文字的颜色 mPaint.setStyle(Paint.Style.FILL);//设置为实心 mPaint.setTextSize(mTextSize);//设置文字的大小 float progress = (currentvalue / 360);//当前的进度,需要转化处理 String result = String.format("%.2f", progress);//保留两位小数 int v = (int) (Float.parseFloat(result) * 100);//取整 String mess = v + "%";//拼揍 Rect rect = new Rect();//边距 mPaint.getTextBounds(mess, 0, mess.length(), rect);//获取文字的边距 int width = rect.width();//文字的宽度 int height = rect.height();//文字的高度 int dx = getMeasuredWidth() / 2 - width / 2;//文字的中心坐标 int dy = getMeasuredHeight() / 2 + height / 2;//文字的中心坐标 canvas.drawText(mess, dx, dy, mPaint); } /** * 画弧度 * * @param canvas */ private void CanvasArc(Canvas canvas) { mPaint.setColor(mSecondColor);//设置圆弧的进度颜色 float left = mWidth;//距离左边的距离 float top = mWidth;//距离上面的距离 float right = getMeasuredWidth() - mWidth;//距离右边的距离 float bottom = getMeasuredWidth() - mWidth;//距离下边的距离 RectF oval = new RectF(left, top, right, bottom); canvas.drawArc(oval, -90, currentvalue, false, mPaint);//false : 不画扇形弧边,只画弧长 } /** * 画圆 * * @param canvas */ private void CanvasCircle(Canvas canvas) { mPaint.setStyle(Paint.Style.STROKE);//设置空心 mPaint.setColor(mFirstColor);//设置画笔的颜色 mPaint.setStrokeWidth(mWidth);//设置画笔的宽度 int dx = getMeasuredWidth() / 2;//圆心x轴的点 int dy = getMeasuredHeight() / 2;//圆心y轴的点 int radius = getMeasuredWidth() / 2 - mWidth; //该圆的半径 = 该View 的宽度 - 圆环的宽度 canvas.drawCircle(dx, dy, radius, mPaint); } /** * @param progress 1-360 设置的时候,自己根据需求来转换 */ public void setProgress(final int progress) { this.mGoal = progress; mHandler.sendEmptyMessageDelayed(1, 10);//发送延迟的消息 } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 1) { currentvalue++;//变量自增 postInvalidate();//通知绘图 if (currentvalue == mGoal) {//条件判断 return; } mHandler.sendEmptyMessageDelayed(1, 10); } } }; }