1. 首页
  2. IT资讯

Android自定义控件 – 彩虹表盘

说实话写代码久了,本能的会避免一些不熟悉的领域,而去做一些擅长的领域,这样使工作显得得心应手,但殊不知这是一种逃避行为,只有不断的面临问题甚至主动制造问题,好比说我偏偏不用setVisible这种老旧的显影方式,而是使用去使用动画,不用常用布局堆叠构建UI,而是使用Canvas绘制布局,虽然说到底还是API调用师,笔者不是要歌颂那些用于尝试的人,只是想对个方法对条路,这也是另一种节约时间成本的方式。

进入正题

国际惯例先上效果图

设计图实现效果
Android自定义控件 - 彩虹表盘Android自定义控件 - 彩虹表盘

看完效果会给我打多少分?··· 基本样式已出,剩下就是精雕细琢了

按照笔者学习借鉴的套路,一般找几个参考案例,百度,GitHub,谷歌三连,是绝对不会少的

案例一

效果: 指针旋转 + 间隔彩虹

package com.xiaomakj.utillib.widget;  import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.DashPathEffect; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PathMeasure; import android.graphics.RectF; import android.graphics.SweepGradient; import android.util.AttributeSet; import android.view.View;   public class GradualView extends View {     public static final int[] SWEEP_GRADIENT_COLORS = new int[]{Color.GREEN, Color.GREEN, Color.BLUE, Color.RED, Color.RED};     private int tableWidth = 50;     private Paint mPaint;     private Path mPath;     private RectF mTableRectF;     //把路径分成虚线段的     private DashPathEffect dashPathEffect;     //给路径上色     private SweepGradient mColorShader;     //指针的路径     private Path mPointerPath;     private float mCurrentDegree = 60;      public GradualView(Context context, AttributeSet attrs) {         super(context, attrs);         mPaint = new Paint();         mPaint.setAntiAlias(true);         mPaint.setDither(true);         mPaint.setColor(Color.BLACK);         mPath = new Path();         mPointerPath = new Path();         startAnimator();     }      @Override     protected void onSizeChanged(int w, int h, int oldw, int oldh) {         super.onSizeChanged(w, h, oldw, oldh);         float size = Math.min(w, h) - tableWidth * 2;         //油表的位置方框         mTableRectF = new RectF(0, 0, size, size);         mPath.reset();         //在油表路径中增加一个从起始弧度         mPath.addArc(mTableRectF, 60, 240);         //计算路径的长度         PathMeasure pathMeasure = new PathMeasure(mPath, false);         float length = pathMeasure.getLength();         float step = length / 60;         dashPathEffect = new DashPathEffect(new float[]{step / 3, step * 2 / 3}, 0);          float radius = size / 2;         mColorShader = new SweepGradient(radius, radius,SWEEP_GRADIENT_COLORS,null);         //设置指针的路径位置         mPointerPath.reset();         mPointerPath.moveTo(radius, radius - 20);         mPointerPath.lineTo(radius, radius + 20);         mPointerPath.lineTo(radius * 2 - tableWidth, radius);         mPointerPath.close();     }      @Override     protected void onDraw(Canvas canvas) {         super.onDraw(canvas);         float dx = (getWidth() - mTableRectF.width()) / 2;         float dy = (getHeight() - mTableRectF.height()) / 2;         //把油表的方框平移到正中间         canvas.translate(dx, dy);         canvas.save();         //旋转画布         canvas.rotate(90, mTableRectF.width() / 2, mTableRectF.height() / 2);         mPaint.setStyle(Paint.Style.STROKE);         mPaint.setStrokeWidth(tableWidth);         mPaint.setPathEffect(dashPathEffect);         mPaint.setShader(mColorShader);         canvas.drawPath(mPath, mPaint);         canvas.restore();         //还原画笔         mPaint.setPathEffect(null);         mPaint.setShader(null);         mPaint.setStyle(Paint.Style.FILL);         mPaint.setStrokeWidth(tableWidth / 10);         canvas.save();         canvas.rotate(150 + mCurrentDegree, mTableRectF.width() / 2, mTableRectF.height() / 2);         canvas.drawPath(mPointerPath, mPaint);         canvas.restore();     }      public void startAnimator() {         ValueAnimator animator = ValueAnimator.ofFloat(0, 240);         animator.setDuration(40000);         animator.setRepeatCount(ValueAnimator.INFINITE);         animator.setRepeatMode(ValueAnimator.RESTART);         animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {             @Override             public void onAnimationUpdate(ValueAnimator animation) {                 mCurrentDegree = (int) (0 + (Float) animation.getAnimatedValue());                 invalidate();             }         });         animator.start();     } }  

案例二

效果:彩虹圆弧 + 图形定位

 package com.example.yan;          import android.content.Context;         import android.graphics.Canvas;         import android.graphics.Paint;         import android.graphics.Rect;         import android.graphics.RectF;         import android.graphics.Shader;         import android.graphics.SweepGradient;         import android.util.AttributeSet;         import android.view.View;  /**  * Created by xiaoyanzi on 2016/3/18.  * 渐变圆弧  */ public class GradualView extends View {      private Context context;     private Paint paint;//画笔     private Paint paintFull;//实心圆画笔     private Paint textPaint;//标识字画笔     private Paint valuePaint;//移动小球画笔     private int[] mColors;//渐变色数组      private int centerX;//中心X     private int centerY;//中心Y     private int srcH;//控件高度     private float startAngle = 110;//圆弧起始角度     private float sweepAngle = 320;//圆弧所占度数     private float airValue = 66;      /**      * 直接在代码中调用时,使用该函数      *      * @param context      */     public GradualView(Context context) {         super(context);         initData(context);     }      /**      * 在xml中使用自定义view时,使用这个函数      *      * @param context      * @param attrs      */     public GradualView(Context context, AttributeSet attrs) {         super(context, attrs);         initData(context);     }      /**      * 可以由上一个函数中手动调用      *      * @param context      * @param atrrs      * @param defStyle 自定义函数中的attrs表示view的属性集,defStyle表示默认的属性资源集的id      */     public GradualView(Context context, AttributeSet atrrs, int defStyle) {         super(context, atrrs, defStyle);     }      /**      * 初始化      *      * @param context      */     private void initData(Context context) {         this.context = context;         paint = new Paint(Paint.ANTI_ALIAS_FLAG);         paint.setStyle(Paint.Style.STROKE);         mColors = new int[]{                 0xFF660099,//紫色                 0xFF330033,//褐色                 0xFF99FF00,//草绿色                 0xFFFFFF00,//黄色                 0xFFFF6600,//橘色                 0xFFFF0000,//红色                 0xFF660099,//紫色          };         Shader s = new SweepGradient(0, 0, mColors, null);         paint.setAntiAlias(true);//设置画笔为无锯齿         paint.setStrokeWidth(dip2px(context, 14));//线宽         paint.setShader(s);         paintFull = new Paint(Paint.ANTI_ALIAS_FLAG);         paintFull.setStyle(Paint.Style.FILL_AND_STROKE);         paintFull.setAntiAlias(true);//设置画笔为无锯齿         paintFull.setShader(s);         textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);         textPaint.setTextSize(dip2px(context, 22));//设置字体大小         textPaint.setColor(0xFFFFFFFF);         valuePaint = new Paint(Paint.ANTI_ALIAS_FLAG);         valuePaint.setAntiAlias(true);//设置画笔为无锯齿     }      public void setAirValue(float airValue) {         this.airValue = airValue;     }      @Override     protected void onSizeChanged(int w, int h, int oldw, int oldh) {         super.onSizeChanged(w, h, oldw, oldh);         srcH = h;         centerX = w / 2;         centerY = h / 2;     }      @Override     protected void onDraw(Canvas canvas) {         super.onDraw(canvas);         float r = srcH / 2 - paint.getStrokeWidth() * 0.5f - dip2px(context, 200); //移动中心         canvas.translate(centerX, centerY);         RectF oval = new RectF();         oval.left = -r;//左边         oval.top = -r;//上边         oval.right = r;//右边         oval.bottom = r;//下边         canvas.drawArc(oval, startAngle, sweepAngle, false, paint); //绘制圆弧 //绘制圆弧两头的小圆         float mr = dip2px(context, 7);         float x1 = (float) (-r * Math.sin((360 - sweepAngle) / 2 * Math.PI / 180));         float y1 = (float) (r * Math.cos((360 - sweepAngle) / 2 * Math.PI / 180));         canvas.drawCircle(x1, y1, mr, paintFull);         float x2 = (float) (r * Math.sin((360 - sweepAngle) / 2 * Math.PI / 180));         float y2 = (float) (r * Math.cos((360 - sweepAngle) / 2 * Math.PI / 180));         canvas.drawCircle(x2, y2, mr, paintFull); //小圆离球的距离         float range = r + dip2px(context, 30);         float ar = 12f; //画周围小球和数字         float ax1 = (float) (-range * Math.sin(45 * Math.PI / 180));         float ay1 = (float) (range * Math.cos(45 * Math.PI / 180));         canvas.drawCircle(ax1, ay1, ar, paintFull);         canvas.drawText("0", ax1 - getTextW() * 3, ay1 + getTextH() / 2, textPaint);         float ax2 = -range;         float ay2 = 0;         canvas.drawCircle(ax2, ay2, ar, paintFull);         canvas.drawText("50", ax2 - getTextW() * 5, ay2 + getTextH() / 2, textPaint);         float ax3 = (float) (-range * Math.sin(45 * Math.PI / 180));         float ay3 = (float) (-range * Math.cos(45 * Math.PI / 180));         canvas.drawCircle(ax3, ay3, ar, paintFull);         canvas.drawText("100", ax3 - getTextW() * 7, ay3 + getTextH() / 2, textPaint);         float ax4 = 0;         float ay4 = -range;         canvas.drawCircle(ax4, ay4, ar, paintFull);         canvas.drawText("150", ax4 - getTextW() * 3, ay4 - getTextH(), textPaint);         float ax5 = (float) (range * Math.sin(45 * Math.PI / 180));         float ay5 = (float) (-range * Math.cos(45 * Math.PI / 180));         canvas.drawCircle(ax5, ay5, ar, paintFull);         canvas.drawText("200", ax5 + getTextW(), ay5 + getTextH() / 2, textPaint);         float ax6 = range;         float ay6 = 0;         canvas.drawCircle(ax6, ay6, ar, paintFull);         canvas.drawText("300", ax6 + getTextW(), ay6 + getTextH() / 2, textPaint);         float ax7 = (float) (range * Math.sin(45 * Math.PI / 180));         float ay7 = (float) (range * Math.cos(45 * Math.PI / 180));         canvas.drawCircle(ax7, ay7, ar, paintFull);         canvas.drawText("500", ax7 + getTextW(), ay7 + getTextH() / 2, textPaint); //画标识小球         valuePaint.setColor(0xFFFFFFFF);         float cx;         float cy;         if (airValue >= 0 && airValue <= 50) {             cx = (float) (-r * Math.cos((45 - airValue * 0.9) * Math.PI / 180));             cy = (float) (r * Math.sin((45 - airValue * 0.9) * Math.PI / 180));         } else if (airValue > 50 && airValue <= 150) {             cx = (float) (-r * Math.cos((airValue * 0.9 - 45) * Math.PI / 180));             cy = (float) (-r * Math.sin((airValue * 0.9 - 45) * Math.PI / 180));         } else if (airValue > 150 && airValue <= 200) {             cx = (float) (-r * Math.cos((airValue * 0.9 - 45) * Math.PI / 180));             cy = (float) (-r * Math.sin((airValue * 0.9 - 45) * Math.PI / 180));         } else if (airValue > 200 && airValue <= 300) {             cx = (float) (-r * Math.cos((airValue * 0.45 + 45) * Math.PI / 180));             cy = (float) (-r * Math.sin((airValue * 0.45 + 45) * Math.PI / 180));         } else if (airValue > 300 && airValue <= 500) {//此处有问题             cx = (float) (r * Math.cos(((airValue - 300) * 0.225) * Math.PI / 180));             cy = (float) (r * Math.sin(((airValue - 300) * 0.225) * Math.PI / 180));         } else {             cx = (float) (-r * Math.cos(45 * Math.PI / 180));             cy = (float) (r * Math.sin(45 * Math.PI / 180));         }         canvas.drawCircle(cx, cy, dip2px(context, 11), valuePaint);         canvas.drawCircle(cx, cy, dip2px(context, 4), paintFull);     }      /**      * dip转px      *      * @param context      * @param dpValue      * @return      */     private int dip2px(Context context, float dpValue) {         final float scale = context.getResources().getDisplayMetrics().density;         return (int) (dpValue * scale + 0.5f);     }      /**      * 获取"正"的高度      *      * @return      */     private float getTextH() {         Paint pFont = new Paint();         Rect rect = new Rect(); //返回包围整个字符串的最小的一个Rect区域         pFont.getTextBounds("正", 0, 1, rect);         return rect.height();     }      /**      * 获取"正"的宽度      *      * @return      */     private float getTextW() {         Paint pFont = new Paint();         Rect rect = new Rect(); //返回包围整个字符串的最小的一个Rect区域         pFont.getTextBounds("正", 0, 1, rect);         return rect.width();     } } 

最终章:合并大法

效果:效果如上图

package com.xiaomakj.utillib.widget;  import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.DashPathEffect; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PathMeasure; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.SweepGradient; import android.util.AttributeSet; import android.view.View;  import com.vondear.rxtool.RxTool; import com.xiaomakj.utillib.R;   /**  * 弧形进度条  *  * @author Vondear  * @date 2015/12/03  */ public class RxRoundProgress extends View {     private int count;     public static final int STROKE = 0;     /**      * 画笔对象的引用      */     private Paint paint;     private Path mPath;     private Paint textPaint;     private Paint centerPaint;     private Paint dotPaint;     private Paint dotTexttPaint;     /**      * 圆环的颜色      */     private int roundColor;     /**      * 圆环进度的颜色      */     private int roundProgressColor;     /**      * 中间进度百分比的字符串的颜色      */     private int textColor;     /**      * 中间进度百分比的字符串的字体      */     private float textSize;     /**      * 圆环的宽度      */     private float roundWidth;     /**      * 最大进度      */     private double max;     /**      * 当前进度      */     private double progress;     /**      * 是否显示中间的进度      */     private boolean textIsDisplayable;     /**      * 进度的风格,实心或者空心      */     private int style;      private int centerX;//中心X     private int centerY;//中心Y     private int srcH;//控件高度      public RxRoundProgress(Context context) {         this(context, null);     }      public RxRoundProgress(Context context, AttributeSet attrs) {         this(context, attrs, 0);     }      public RxRoundProgress(Context context, AttributeSet attrs, int defStyle) {         super(context, attrs, defStyle);          //进度条画笔         paint = new Paint();         mPath = new Path();         //文字画笔         textPaint = new Paint();         //文字画笔         centerPaint = new Paint();         //文字画笔         dotPaint = new Paint();         //文字画笔         dotTexttPaint = new Paint();         TypedArray mTypedArray = context.obtainStyledAttributes(attrs,                 R.styleable.RxRoundProgress);          //获取自定义属性和默认值         roundColor = mTypedArray.getColor(R.styleable.RxRoundProgress_roundColor, Color.WHITE);         roundProgressColor = mTypedArray.getColor(R.styleable.RxRoundProgress_roundProgressColor, Color.parseColor("#F6B141"));         textColor = mTypedArray.getColor(R.styleable.RxRoundProgress_textColor, Color.GREEN);         textSize = mTypedArray.getDimension(R.styleable.RxRoundProgress_textSize1, 15);         roundWidth = mTypedArray.getDimension(R.styleable.RxRoundProgress_roundWidth, 20);         max = mTypedArray.getInteger(R.styleable.RxRoundProgress_max, 100);         textIsDisplayable = mTypedArray.getBoolean(R.styleable.RxRoundProgress_textIsDisplayable, true);         style = mTypedArray.getInt(R.styleable.RxRoundProgress_style, 0);         mTypedArray.recycle();          textPaint.setColor(roundColor);         textPaint.setAntiAlias(true);         textPaint.setTextSize(dp2px(13));          dotPaint.setStyle(Paint.Style.STROKE);         dotPaint.setAntiAlias(true);          dotTexttPaint.setStyle(Paint.Style.FILL);         dotTexttPaint.setAntiAlias(true);         dotTexttPaint.setTextSize(dp2px(12));          //中间分数         centerPaint.setColor(textColor);         centerPaint.setAntiAlias(true);     }      int[] mColors = new int[]{             Color.GREEN, 0xFF12B8CA,             Color.RED, Color.RED,             Color.YELLOW, Color.YELLOW,             Color.BLUE, Color.GREEN,     };      /**      * dp转px      *      * @param dpValue dp值      * @return px值      */     public int dp2px(float dpValue) {         final float scale = RxTool.getContext().getResources().getDisplayMetrics().density;         return (int) (dpValue * scale + 0.5f);     }      @Override     protected void onSizeChanged(int w, int h, int oldw, int oldh) {         super.onSizeChanged(w, h, oldw, oldh);         srcH = h;         centerX = w / 2;         centerY = h / 2;      }      @Override     protected void onDraw(Canvas canvas) {         super.onDraw(canvas);         /**          * 画最外层的大圆环          */         //向右边取启点         //间距         int margin = dp2px(2);         int tPadding = dp2px(40);         //获取圆心的x坐标         int center = getWidth() / 2 - tPadding;         //圆环的半径         int radius = (int) (center - roundWidth / 2);         //用于定义的圆弧的形状和大小的界限         RectF innerOval = new RectF(center - radius + tPadding, center - radius + tPadding, center + radius + tPadding, center + radius + tPadding);         int outWidth = dp2px(20);         RectF outOval = new RectF(center - radius + tPadding - outWidth, center - radius + tPadding - outWidth, center + radius + tPadding + outWidth, center + radius + tPadding + outWidth);         //画外圆         mPath.reset();         mPath.addArc(outOval, 135, 270);         //计算路径的长度         PathMeasure pathMeasure = new PathMeasure(mPath, false);         float length = pathMeasure.getLength();         float step = length / 60;         DashPathEffect dashPathEffect = new DashPathEffect(new float[]{step / 3, step * 2 / 3}, 0);         SweepGradient mColorShader = new SweepGradient(centerX, centerX, mColors, null);         paint.setPathEffect(dashPathEffect);         //設置彩色         paint.setShader(mColorShader);         //设置空心         paint.setStyle(Paint.Style.STROKE);         //设置圆环的宽度         paint.setStrokeWidth(roundWidth / 2);         //消除锯齿         paint.setAntiAlias(true);         paint.setStrokeCap(Paint.Cap.BUTT);         canvas.drawPath(mPath, paint);         //画内圆         mPath.reset();         mPath.addArc(innerOval, 135, 270);         //消除间隔         paint.setPathEffect(null);         paint.setStrokeWidth(roundWidth);         //設置彩色         canvas.drawPath(mPath, paint);          //放弃灰底色圆 //        paint.setStrokeCap(Paint.Cap.ROUND); //        paint.setStrokeWidth(roundWidth); //        paint.setColor(roundColor); //        paint.setPathEffect(null); //        //設置彩色 //        paint.setShader(null);         //根据进度画圆弧 //        canvas.drawArc(innerOval, 135, 270, false, paint);   //		canvas.drawRect(0, 0, getWidth(), getWidth(), paint);// 正方形         centerPaint.setTextSize(dp2px(18));         float textH = getTextH(centerPaint, ((int) getProgress()) + "");         canvas.drawText(                 ((int) getProgress()) + "",                 (center + tPadding) - centerPaint.measureText((int) getProgress() + "") / 2,                 center + tPadding + textH + radius / 2, centerPaint);         centerPaint.setTextSize(dp2px(14));         float textH2 = getTextH(centerPaint, "平均成绩");         canvas.drawText(                 "平均成绩",                 (center + tPadding) - centerPaint.measureText("平均成绩") / 2,                 center + tPadding + textH + textH2 + margin * 2 + radius / 2, centerPaint);         centerPaint.setTextSize(dp2px(12));         float textH3 = getTextH(centerPaint, "已完成考试" + count + "次");         canvas.drawText(                 "已完成考试" + count + "次",                 (center + tPadding) - centerPaint.measureText("已完成考试" + count + "次") / 2,                 center + tPadding + textH + textH2 + textH3 + margin * 3 + radius / 2, centerPaint);          //左边最小值 //        canvas.drawText("0分", (float) (radius - Math.sqrt(2) * (radius / 2) + 10), (float) (2 * radius - Math.sqrt(2) * (radius / 4) + 130), textPaint);         //右边最大值 //        canvas.drawText(getMax() + "分", (float) (radius + Math.sqrt(2) * (radius / 2) + 138), (float) (2 * radius - Math.sqrt(2) * (radius / 4) + 130), textPaint); 		/*if(progress<50){ 			double money = progress*1+(Math.floor(Math.random()*getMax())); 			canvas.drawText(money+"", (center+toright) - centerPaint.measureText(money+"")/2-15, center+165, centerPaint);//右边最大值 		}else{*/         //}         //右边最大值 //        canvas.drawText("分", (center + toright) + centerPaint.measureText(RxDataTool.format2Decimals(getProgress() + "")) / 2 - 10, center + 105, dotPaint);           int[] mColors = new int[]{                 0xFFFF0000,//红色                 0xFFFFFF00,//黄色                 0xFF0B74FE,//蓝色                 0xFF99FF00//草绿色         };         String[] mStrings = new String[]{                 "差",//红色                 "中",//黄色                 "良",//蓝色                 "优"//草绿色         };         for (int i = 0; i < mColors.length; i++) {             dotPaint.setColor(mColors[i]);             dotTexttPaint.setColor(mColors[i]);             canvas.drawCircle(tPadding * 2 / 3 + i / 5f * getWidth(), getHeight() - dp2px(7.5f),                     dp2px(5), dotPaint);             canvas.drawText(                     mStrings[i],                     tPadding * 2 / 3 + i / 5f * getWidth() + getTextW(dotTexttPaint, mStrings[i]) / 2 + margin,                     getHeight() - dp2px(10) + getTextH(dotTexttPaint, mStrings[i]) / 2,                     dotTexttPaint);          } //        /** //         * 画进度百分比 //         */ //        paint.setStrokeWidth(0); //        paint.setColor(textColor); //        paint.setTextSize(textSize); //        //设置字体 //        paint.setTypeface(Typeface.DEFAULT_BOLD); //        //中间的进度百分比,先转换成float在进行除法运算,不然都为0 //        int percent = (int) (((float) progress / (float) max) * 100); //        //测量字体宽度,我们需要根据字体的宽度设置在圆环中间 //        float textWidth = paint.measureText(percent + "%"); // //        if (textIsDisplayable && percent != 0 && style == STROKE) { ////            canvas.drawText(percent + "%", center + toright - textWidth / 2, center + toright + textSize / 2, paint); //画出进度百分比 //        }           //还原画笔         paint.setPathEffect(null);         paint.setShader(null);         paint.setStyle(Paint.Style.FILL);         Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pointer);         Rect bitmapRec = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());         RectF pointerOval = new RectF(                 center + tPadding - bitmap.getWidth() / 2,                 center + tPadding - bitmap.getWidth() / 2,                 center + tPadding + bitmap.getHeight() / 2,                 center + tPadding + bitmap.getHeight() / 2);         Matrix matrix = new Matrix();         matrix.postRotate(-90-45 + 270 * ((float) progress / (float) max), bitmapRec.width() / 2, bitmapRec.height());         matrix.postTranslate(pointerOval.centerX()-bitmap.getWidth()/2, pointerOval.centerY()-bitmap.getHeight());         canvas.drawBitmap(bitmap, matrix, paint);         //canvas.drawBitmap(bitmap, bitmapRec, pointerOval, paint);           /**          * 画圆弧 ,画圆环的进度          */         //设置进度是实心还是空心         paint.setStrokeWidth(roundWidth); //设置圆环的宽度         paint.setColor(roundProgressColor);  //设置进度的颜色         paint.setAntiAlias(true);         switch (style) {             case STROKE: {                 paint.setStyle(Paint.Style.STROKE);                 if (progress >= 0) {                     canvas.drawArc(innerOval, 45, (270 * ((float) progress / (float) max - 1)), false, paint);  //根据进度画圆弧                 }                 break;             }             default:                 break;         }     }      public synchronized double getMax() {         return max;     }      /**      * 设置进度的最大值      *      * @param max      */     public synchronized void setMax(double max) {         if (max < 0) {             throw new IllegalArgumentException("max not less than 0");         }         this.max = max;     }      /**      * 获取进度.需要同步      *      * @return      */     public synchronized double getProgress() {         return progress;     }      /**      * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步      * 刷新界面调用postInvalidate()能在非UI线程刷新      *      * @param progress      */     public synchronized void setProgress(double progress) {         if (progress < 0) {             this.progress = progress;             //throw new IllegalArgumentException("progress not less than 0");         }         if (progress > max) {             progress = max;         }         if (progress <= max) {             this.progress = progress;             postInvalidate();         }      }       /**      * 获取"正"的高度      *      * @return      */     private float getTextH(Paint pFont, String text) {         Rect rect = new Rect(); //返回包围整个字符串的最小的一个Rect区域         pFont.getTextBounds(text, 0, 1, rect);         return rect.height();     }      /**      * 获取"正"的宽度      *      * @return      */     private float getTextW(Paint pFont, String text) {         Rect rect = new Rect(); //返回包围整个字符串的最小的一个Rect区域         pFont.getTextBounds(text, 0, 1, rect);         return rect.width();     }      public int getCricleColor() {         return roundColor;     }      public void setCricleColor(int cricleColor) {         this.roundColor = cricleColor;     }      public int getCricleProgressColor() {         return roundProgressColor;     }      public void setCricleProgressColor(int cricleProgressColor) {         this.roundProgressColor = cricleProgressColor;     }      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 getRoundWidth() {         return roundWidth;     }      public void setRoundWidth(float roundWidth) {         this.roundWidth = roundWidth;     }      public int setCount(int count) {         return this.count;     }  } 

style

    <declare-styleable name="RxRoundProgress">         <attr format="color" name="roundColor"/>         <attr format="color" name="roundProgressColor"/>         <attr format="dimension" name="roundWidth"/>         <attr format="color" name="textColor"/>         <attr format="dimension" name="textSize1"/>         <attr format="integer" name="max"/>         <attr format="boolean" name="textIsDisplayable"/>         <attr name="style">             <enum name="STROKE" value="0"/>             <enum name="FILL" value="1"/>         </attr>     </declare-styleable> 

可以看出来笔者自己写的也是二开版本,面向对象不就是只要结果,不讲过程吗?嘿嘿

发布了142 篇原创文章 · 获赞 42 · 访问量 18万+

原文始发于:Android自定义控件 – 彩虹表盘

主题测试文章,只做测试使用。发布者:程序员,转转请注明出处:http://www.cxybcw.com/146465.html

联系我们

13687733322

在线咨询:点击这里给我发消息

邮件:1877088071@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code