请看源码,注释神马的都很清楚
1、java代码
package com.xctz.niceman.customcanvas; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Shader; import android.util.AttributeSet; import android.view.View; /** * Created by LuanXianSheng on 2016/11/3. */ public class ColorfulRingProgressView extends View { private float mPercent ; //起始进度条的值 private float mStrokeWidth ; //进度条的宽度 private int mBgColor = 0xffe1e1e1 ; //进度条北京的颜色 private float mStartAngle ; //进度条起始角度 private int mFgColorStart = 0xffffe400 ;//进度条起始颜色 private int mFgColorEnd = 0xffffe800 ;//进度条结束的颜色 private LinearGradient mShader ; //线性渐变 private Context mContext ; private Paint mPaint ; private RectF mOval ; private ColorfulRingProgressView(Context context) { super(context); } private ColorfulRingProgressView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context ; //获取自定属性里面的值 TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ColorfulRingProgressView, 0, 0) ; try { mBgColor = typedArray.getColor(R.styleable.ColorfulRingProgressView_bgColor,0xffe1e1e1) ; mFgColorStart = typedArray.getColor(R.styleable.ColorfulRingProgressView_fgColorStart,0xffffe400) ; mFgColorEnd = typedArray.getColor(R.styleable.ColorfulRingProgressView_fgColorEnd,0xffffe800) ; mStrokeWidth = typedArray.getDimension(R.styleable.ColorfulRingProgressView_strokeWidth,dpTopx(20)) ; mStartAngle = typedArray.getFloat(R.styleable.ColorfulRingProgressView_startAngle,0)+270 ; mPercent = typedArray.getFloat(R.styleable.ColorfulRingProgressView_percent,0) ; }catch (Exception e){ typedArray.recycle(); } init(); } /** *将dp转化为px * @param dp * @return */ private int dpTopx(float dp){ return (int)(mContext.getResources().getDisplayMetrics().density * dp + 0.5f); } /** * 初始化设置 */ private void init(){ mPaint = new Paint() ; mPaint.setStyle(Paint.Style.STROKE); mPaint.setAntiAlias(true); mPaint.setStrokeWidth(mStrokeWidth); mPaint.setStrokeCap(Paint.Cap.ROUND); //设置画笔为圆角 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //===========先画圆环的背影色============== mPaint.setShader(null) ; mPaint.setColor(mBgColor); canvas.drawArc(mOval, 0, 360, false, mPaint); //===============正式画progress的进度条的值========= mPaint.setShader(mShader) ;//进度条的颜色是渐变地 canvas.drawArc(mOval, mStartAngle, mPercent * 3.6f, false, mPaint); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //实时监听数值的改变,及时更新 updateOval(); mShader = new LinearGradient(mOval.left,mOval.top,mOval.left,mOval.bottom,mFgColorStart,mFgColorEnd, Shader.TileMode.MIRROR) ; } /** * 更新progress进度条的大小 */ private void updateOval() { int xp = getPaddingLeft() + getPaddingRight() ; int yp = getPaddingBottom() +getPaddingTop() ; mOval = new RectF(getPaddingLeft()+mStrokeWidth, getPaddingTop()+mStrokeWidth, getPaddingLeft()+(getWidth()-xp)-mStrokeWidth, getPaddingTop()+(getHeight()-yp)-mStrokeWidth); } public void refreshTheLayout(){ invalidate(); requestLayout(); } public float getmPercent() { return mPercent; } public void setmPercent(float mPercent) { this.mPercent = mPercent; refreshTheLayout(); } public float getmStrokeWidth() { return mStrokeWidth; } public void setmStrokeWidth(float mStrokeWidth) { this.mStrokeWidth = mStrokeWidth; mPaint.setStrokeWidth(mStrokeWidth); updateOval(); refreshTheLayout(); } public void setStrokeWidthDp(float dp){ this.mStrokeWidth = dpTopx(dp) ; mPaint.setStrokeWidth(mStrokeWidth); updateOval(); refreshTheLayout(); } public int getmFgColorStart() { return mFgColorStart; } public void setmFgColorStart(int mFgColorStart) { this.mFgColorStart = mFgColorStart; mShader = new LinearGradient(mOval.left,mOval.top,mOval.left,mOval.bottom,mFgColorStart,mFgColorEnd, Shader.TileMode.MIRROR) ; refreshTheLayout(); } public int getmFgColorEnd() { return mFgColorEnd; } public void setmFgColorEnd(int mFgColorEnd) { this.mFgColorEnd = mFgColorEnd; mShader = new LinearGradient(mOval.left,mOval.top,mOval.left,mOval.bottom,mFgColorStart,mFgColorEnd, Shader.TileMode.MIRROR) ; refreshTheLayout(); } public float getmStartAngle() { return mStartAngle; } public void setmStartAngle(float mStartAngle) { this.mStartAngle = mStartAngle +270; refreshTheLayout(); } }
2、attr代码
<declare-styleable name="ColorfulRingProgressView"> <attr name="bgColor" /> <attr name="fgColorStart" format="color"/> <attr name="fgColorEnd" format="color"/> <attr name="strokeWidth" format="dimension"/> <attr name="percent" format="float"/> <attr name="startAngle" format="float"/> </declare-styleable>