前言

灵感来自几天前看到一位作者的仿芝麻信用自定义View的文章很不错,所以我换了一种方式来进行实现,写了旧版和新版芝麻信用分仪表盘的效果。

Github地址:
https://github.com/HotBitmapGG/CreditSesameRingView

截图

这是我做的效果,还是有点差距的,嘿嘿。

正文

芝麻信用分的实现

首先初始化各种画笔,默认的size,padding,小圆点.
(因为实在找不到原版芝麻信用的带点模糊效果的小圆点,所以只好用这个代替)

//View的默认大小
defaultSize = dp2px(250);
//默认Padding大小
arcDistance = dp2px(14);//外层圆环画笔
mMiddleArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mMiddleArcPaint.setStrokeWidth(8);
mMiddleArcPaint.setColor(Color.WHITE);
mMiddleArcPaint.setStyle(Paint.Style.STROKE);
mMiddleArcPaint.setAlpha(80);//内层圆环画笔
mInnerArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mInnerArcPaint.setStrokeWidth(30);
mInnerArcPaint.setColor(Color.WHITE);
mInnerArcPaint.setAlpha(80);
mInnerArcPaint.setStyle(Paint.Style.STROKE);//正中间字体画笔
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(Color.WHITE);
mTextPaint.setTextAlign(Paint.Align.CENTER);//圆环大刻度画笔
mCalibrationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCalibrationPaint.setStrokeWidth(4);
mCalibrationPaint.setStyle(Paint.Style.STROKE);
mCalibrationPaint.setColor(Color.WHITE);
mCalibrationPaint.setAlpha(120);//圆环小刻度画笔
mSmallCalibrationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mSmallCalibrationPaint.setStrokeWidth(1);
mSmallCalibrationPaint.setStyle(Paint.Style.STROKE);
mSmallCalibrationPaint.setColor(Color.WHITE);
mSmallCalibrationPaint.setAlpha(130);//圆环刻度文本画笔
mCalibrationTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCalibrationTextPaint.setTextSize(30);
mCalibrationTextPaint.setColor(Color.WHITE);//外层进度画笔
mArcProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mArcProgressPaint.setStrokeWidth(8);
mArcProgressPaint.setColor(Color.WHITE);
mArcProgressPaint.setStyle(Paint.Style.STROKE);
mArcProgressPaint.setStrokeCap(Paint.Cap.ROUND);//外层圆环上小圆点Bitmap画笔
mBitmapPaint = new Paint();
mBitmapPaint.setStyle(Paint.Style.FILL);
mBitmapPaint.setAntiAlias(true);//初始化小圆点图片
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_circle);
//当前点的实际位置
pos = new float[2];
//当前点的tangent值
tan = new float[2];
matrix = new Matrix();

代码很简单,就是各种初始化,往下看.

View的测量,主要在给设置warp_content时候给定一个默认宽高值.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
setMeasuredDimension(resolveMeasure(widthMeasureSpec, defaultSize),    resolveMeasure(heightMeasureSpec, defaultSize));}//根据传入的值进行测量
public int resolveMeasure(int measureSpec, int defaultSize){
int result = 0;
int specSize = MeasureSpec.getSize(measureSpec);
switch (MeasureSpec.getMode(measureSpec))   {      case MeasureSpec.UNSPECIFIED:          result = defaultSize;           break;       case MeasureSpec.AT_MOST:          //设置warp_content时设置默认值           result = Math.min(specSize, defaultSize);          break;        case MeasureSpec.EXACTLY:           //设置math_parent 和设置了固定宽高值           break;        default:           result = defaultSize;  }   return result;}

然后确定View的宽高后的回调方法.

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh){   super.onSizeChanged(w, h, oldw, oldh);   width = w;   height = h;    radius = width / 2;
//外层圆环矩形mMiddleRect = new RectF(defaultPadding, defaultPadding,width - defaultPadding, height - defaultPadding);
//内层圆环矩形mInnerRect = new RectF(defaultPadding + arcDistance, defaultPadding + arcDistance,width - defaultPadding - arcDistance, height - defaultPadding - arcDistance);
// 外层进度矩形mMiddleProgressRect = new RectF(defaultPadding, defaultPadding,width - defaultPadding, height - defaultPadding);
}

这里就是初始化圆弧所需要的矩形实现,下边开始进行重点,绘制,
绘制外层的圆弧,很简单, 圆弧的起始角度,角度.

private void drawMiddleArc(Canvas canvas){
canvas.drawArc(mMiddleRect, mStartAngle, mEndAngle, false, mMiddleArcPaint);
}

绘制内层圆弧

private void drawInnerArc(Canvas canvas){   canvas.drawArc(mInnerRect, mStartAngle, mEndAngle, false, mInnerArcPaint);
}

绘制内层圆弧上的小刻度,画布旋转到圆弧左下角起点,计算出每条刻度线的起始点后,整个圆弧是210度,
每6角度绘制一条刻度线.

private void drawSmallCalibration(Canvas canvas){    //旋转画布    canvas.save();   canvas.rotate(-105, radius, radius);    //计算刻度线的起点结束点    int startDst = (int) (defaultPadding + arcDistance - mInnerArcPaint.getStrokeWidth() / 2 - 1);   int endDst = (int) (startDst + mInnerArcPaint.getStrokeWidth());    for (int i = 0; i <= 35; i++)    {        //每旋转6度绘制一个小刻度       canvas.drawLine(radius, startDst, radius, endDst, mSmallCalibrationPaint);        canvas.rotate(6, radius, radius);
}
canvas.restore();
}

绘制内层圆弧上的大刻度,350, 550, 600,650, 700, 950,对应的信用分值,
一样旋转画布,计算刻度线的起始点,计算出每次旋转的角度,每35度旋转一次,依次绘制对应的大刻度线,
然后绘制对应的文本内容,使用paint的measureText方法测量出文本的长度,依次绘制对应的文本内容.

private void drawCalibrationAndText(Canvas canvas){   //旋转画布进行绘制对应的刻度    canvas.save();   canvas.rotate(-105, radius, radius);    //计算刻度线的起点结束点    int startDst = (int) (defaultPadding + arcDistance - mInnerArcPaint.getStrokeWidth() / 2 - 1);    int endDst = (int) (startDst + mInnerArcPaint.getStrokeWidth());    //刻度旋转的角度    int rotateAngle = 210 / 10;    for (int i = 1; i < 12; i++)    {       if (i % 2 != 0)        {            canvas.drawLine(radius, startDst, radius, endDst, mCalibrationPaint);       }        // 测量文本的长度
float textLen = mCalibrationTextPaint.measureText(sesameStr[i - 1]);
canvas.drawText(sesameStr[i - 1], radius - textLen / 2, endDst + 40, mCalibrationTextPaint);
canvas.rotate(rotateAngle, radius, radius);
}
canvas.restore();}

绘制中间的信用分值,信用等级,评估时间等文本,这个比较简单,直接drawText,依次高低排列绘制即可.

private void drawCenterText(Canvas canvas){    //绘制Logo    mTextPaint.setTextSize(30);    canvas.drawText("BETA", radius, radius - 130, mTextPaint);   //绘制信用分数    mTextPaint.setTextSize(200);   mTextPaint.setStyle(Paint.Style.STROKE);    canvas.drawText(String.valueOf(mMinNum), radius, radius + 70, mTextPaint);   //绘制信用级别    mTextPaint.setTextSize(80);    canvas.drawText(sesameLevel, radius, radius + 160, mTextPaint);    //绘制评估时间    mTextPaint.setTextSize(30);    canvas.drawText(evaluationTime, radius, radius + 205, mTextPaint);
}

绘制最外层的进度,这里使用的Path添加要绘制的圆弧,因为需要去不断的计算坐标点,主要用到了PathMeasure这个类,将绘制的圆弧加入到path中,

当前点的实际位置
private float[] pos;

当前的tangent值
private float[] tan;

获取路径的终点的正切值和坐标,然后根据坐标点绘制小圆点
PathMeasure pathMeasure = new PathMeasure(path, false);
pathMeasure.getPosTan(pathMeasure.getLength() * 1, pos, tan);

关于PathMeasure,推荐看AndroidNote,我也是跟着这个笔记学习的自定义控件.

private void drawRingProgress(Canvas canvas){   Path path = new Path();    path.addArc(mMiddleProgressRect, mStartAngle, mCurrentAngle);PathMeasure pathMeasure = new PathMeasure(path, false);pathMeasure.getPosTan(pathMeasure.getLength() * 1, pos, tan);    matrix.reset();    matrix.postTranslate(pos[0] - bitmap.getWidth() / 2, pos[1] - bitmap.getHeight() / 2);canvas.drawPath(path, mArcProgressPaint);    //起始角度不为0时候才进行绘制小圆点    if (mCurrentAngle == 0)       return;    canvas.drawBitmap(bitmap, matrix, mBitmapPaint);   mBitmapPaint.setColor(Color.WHITE);    canvas.drawCircle(pos[0], pos[1], 8, mBitmapPaint);
}

好了,到这里所有绘制完毕了,接下来让圆弧进度条动起来吧,使用ValueAnimator,
进度条动画定义了圆弧进度条的开始角度mCurrentAngle,圆弧角度mTotalAngle,
数值动画定义了初始化minNum=0,maxNum根据传入的数值进行计算.

public void startAnim(){    ValueAnimator mAngleAnim = ValueAnimator.ofFloat(mCurrentAngle, mTotalAngle); mAngleAnim.setInterpolator(new AccelerateDecelerateInterpolator()); mAngleAnim.setDuration(3000);    mAngleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){        @Override      public void onAnimationUpdate(ValueAnimator valueAnimator){           mCurrentAngle = (float) valueAnimator.getAnimatedValue();            postInvalidate();        }
});   mAngleAnim.start();    ValueAnimator mNumAnim = ValueAnimator.ofInt(mMinNum, mMaxNum);mNumAnim.setDuration(3000);    mNumAnim.setInterpolator(new LinearInterpolator());    mNumAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override        public void onAnimationUpdate(ValueAnimator valueAnimator){            mMinNum = (int) valueAnimator.getAnimatedValue();           postInvalidate();       }
});   mNumAnim.start();}

最后根据传入的信用分值计算圆弧进度条所到的角度.

public void setSesameValues(int values){   if (values <= 350){       mMaxNum = values;        mTotalAngle = 0f;        sesameLevel = "信用较差";        evaluationTime = "评估时间:" + getCurrentTime();    } else if (values <= 550){        mMaxNum = values;        mTotalAngle = (values - 350) * 80 / 400f + 2;        sesameLevel = "信用较差";        evaluationTime = "评估时间:" + getCurrentTime();    } else if (values <= 700){        mMaxNum = values;        if (values > 550 &amp;&amp; values <= 600){           sesameLevel = "信用中等";        } else if (values > 600 &amp;&amp; values <= 650){            sesameLevel = "信用良好";        } else {            sesameLevel = "信用优秀";        }        mTotalAngle = (values - 550) * 120 / 150f + 43;       evaluationTime = "评估时间:" + getCurrentTime();    } else if (values <= 950){        mMaxNum = values;        mTotalAngle = (values - 700) * 40 / 250f + 170;        sesameLevel = "信用极好";        evaluationTime = "评估时间:" + getCurrentTime();    } else{        mTotalAngle = 240f;    }    startAnim();
}

最后

这篇文章只分析了新版的实现过程,旧版的的实现思路也差不多,代码也不复杂,可以直接看源码实现,由于本人文章写的不多,所以感觉把代码的实现用语言来组织还真挺难的,所以写的不好的地方还请各位大大见谅,有问题可联系我,最后希望如果觉得还可以的,请给个star, 谢谢啦.

自定义View仿支付宝芝麻信用分仪表盘效果相关推荐

  1. Android 仿芝麻信用进度条,自定义View仿支付宝芝麻信用分仪表盘效果

    image 前言 灵感来自几天前看到一位作者的仿芝麻信用自定义View的文章很不错,所以我换了一种方式来进行实现,写了旧版和新版芝麻信用分仪表盘的效果. 截图 这是我做的效果,还是有点差距的,嘿嘿. ...

  2. android 自定义中文加盘,Android自定义View仿支付宝芝麻信用分仪表盘

    先看下iOS的芝麻信用分截图 这是我做的效果,还是有点差距的 支付宝9.9版本芝麻信用分的实现 首先初始化各种画笔,默认的size,padding,小圆点. (因为实在找不到原版芝麻信用的带点模糊效果 ...

  3. 支付宝 android ui,Android 仿支付宝芝麻信用分仪表盘效果 CreditSesameRingView

    软件介绍 自定义View之仿支付宝芝麻信用分仪表盘效果,喜欢的话,请给个star,谢谢. 使用添加项目依赖Add it in your root build.gradle at the end of  ...

  4. android自定义表盘部件,Android自定义view仿支付宝芝麻信用表盘

    演示效果 实现步骤: 1.画不同宽度和半径的内外圆弧 2.通过循环旋转canvas,在固定位置绘制短线刻度,长线刻度,刻度文字 3.绘制view中心几个文本,并调整位置 4.实时更新当前旋转角度刷新小 ...

  5. 自定义View之仿支付宝v9.9芝麻信用分仪表盘效果

    点击上方蓝字关注公众号 码个蛋第242次推文 因为信用,所以简单 作者:hotBitmapGG 博客:http://www.jianshu.com/u/566d6cec0ebc 文章目录 前言 截图 ...

  6. echarts仿支付宝芝麻信用分环形图

    效果图 配置 // 支付宝芝麻信用环形图const options = {graphic: [ //为环形图中间添加文字{type: "text",left: "cent ...

  7. 自定义View实现支付宝芝麻信用页面功能

    此篇文章布局有些问题,调整后的请看这篇:http://blog.csdn.net/anny_lin/article/details/50507608 今天在使用支付宝的事后,突然发现了一个叫做芝麻信用 ...

  8. 自定义xy组 android,Android自定义view之仿支付宝芝麻信用仪表盘示例

    自定义view练习 仿支付宝芝麻信用的仪表盘 对比图: 首先是自定义一些属性,可自己再添加,挺基础的,上代码 接着在构造方法里初始化自定义属性和画笔: private void initAttr(At ...

  9. Android自定义view之仿支付宝芝麻信用仪表盘 ---by ccy

    自定义view练习 仿支付宝芝麻信用的仪表盘 对比图: 首先是自定义一些属性,可自己再添加,挺基础的,上代码 <?xml version="1.0" encoding=&qu ...

最新文章

  1. ZooKeeper私人学习笔记
  2. 预处理器预处理变量头文件保护条件编译
  3. 专栏 | 基于 Jupyter 的特征工程手册:数据预处理(二)
  4. Vim杂记:Sublime的配色方案
  5. 更改整个目录文件的所有权限
  6. c++清空串口缓冲区
  7. ie浏览器升级_微软呼吁用户停用IE浏览器 2020年将不再更新升级
  8. 安装DotNetCore.1.0.0-VS2015Tools.Preview2.exe 错误Error 0x81f40001 解决方法
  9. Spring中使用 InitializingBean
  10. S3C2440移植uboot之支持NAND启动
  11. 智能手机与pc计算机的区别,手机cpu和电脑cpu有什么区别
  12. 安卓10和android区别,华为8月9日发布安卓10.0系统 华为EMUI 10.0功能及适配机型 华为安卓系统和鸿蒙OS区别...
  13. 从此告别PPT制作的烦恼:ChatGPT和MindShow帮你快速完成
  14. 单边指数信号的特点_单边带通信的特点
  15. deform服务器位置,Deform V11 自动多工步分析(MO)设置详解-工艺成型及仿真
  16. win10 + Ubuntu 20.04 LTS 双系统安装 (UEFI + GPT)(图文,多图预警)
  17. Unity ACT游戏相机逻辑
  18. 限制input 输入框只能输入纯数字/数字/中文/英文
  19. linux学习(一)虚拟机界面全屏
  20. 如果你的键盘也没有大小写和数字指示灯

热门文章

  1. sdk - 软件开发工具包
  2. Flink CheckPoint机制简介
  3. 基于静态和动态特征融合的语音情感识别层次网络
  4. manjaro安装python_manjaro安装以及配置
  5. linux 系统在机顶盒和wifi卡上运行
  6. JS事件代理(也称事件委托)是什么,及实现原理
  7. 开源远程工具linux,Linux下四款常见远程工具比较
  8. python调整视频播放速度
  9. html页面visible,Html学习 display:none与visible:hidden的区别
  10. python多久可以精通_Python要学习多久可以掌握?多久可以精通?