android之自定义带文本的圆角进度条
2016-05-26 11:02
399 查看
自定义圆角进度条以及颜色渐变的进度条
先上图,给个直观印象
一、先来看看渐变的圆角
2、初始化画笔,圆角主要是setStrokeCap(Cap.ROUND)来设置的,而设置抖动setDither()这个大概意思是保证画图的清晰度已经平滑度,抗锯齿setAntiAlias();表示画出来的视图不会有锯齿
二、再来看看其onMeasure和onDraw()方法:
1、主要是测量视图的宽高,然后通过setMeasuredimension来设置其测量的宽高
高能预警:此处有个坑,天大的坑 :mRadius 在这里不断的赋值,由于onMeasure不单单执行一次,在测量期间会执行多次,导致mRadius一直在变化,导致逐渐变小或变大,导致视图可能会变的更大或视图不可见,所以这种初始化的赋值,建议放在初始化或ondraw中,就不会有这种问题。。。这里出现问题就直接拿出来跟大家分享,代码我也没改正,圆角渐变代码我并没有改正,但是色环的已经改正了,代码都差不多,自行参考
2、onDraw方法中 首先因为起始角度(0角度)是x轴方向,所以要旋转画布到自己所需要的开始绘制的地方,这里将画布旋转115,即绘制的起始点;此外由于画笔是从画笔的宽度中心点开始绘制的所以mRadius半径mSize减去画笔跨度的一半再除以2,就是画圆的半径 即(
,而后drawArc就是画弧,第一次调用就是画弧的背景,第二次才是画弧的进度,画弧的时候起始角度是从5开始,因为,画笔是从中间开始的,而由于是渐变色(SweepGradent类控制的)前一半圆弧的颜色是往前取的所以会导致有色差,所以起始角度往后一移动5个角度(可根据画笔宽度的一半来取),这也是为什么只旋转115而不是120角度的原因。
二、色环的代码跟圆弧的差不多,依葫芦画瓢,相信读者都有举一反三的能力,这里就不再讲解,需要的可下载demo查看源码
demo:http://download.csdn.net/detail/zhongwn/9531575
先上图,给个直观印象
一、先来看看渐变的圆角
private void init(AttributeSet attrs) { mRadius = (int) ((getScreenSize(context).x * 0.6f) / 2);//屏幕的1/4 initPaint(); } private void initPaint() { // 初始化画笔对象 mPaint.setStyle(Style.STROKE); mPaint.setAntiAlias(true); mPaint.setDither(true);//设置抖动 mPaint.setStrokeCap(Cap.ROUND); mPaintUnReach.setStyle(Style.STROKE); mPaintUnReach.setAntiAlias(true); mPaintUnReach.setDither(true); mPaintUnReach.setStrokeCap(Cap.ROUND); // 设置画笔颜色和宽度 mPaintUnReach.setColor(mUnReachBarColor); mTextPaint.setStyle(Style.FILL); mTextPaint.setAntiAlias(true); mTextPaint.setDither(true); }1、初始化画笔及画圆的半径,半径非常重要,会影响圆的宽高,读者可根据自己需要提供一个公用方法设置或者自定义属性实现,现只是为了讲解,取屏幕w的1/4为半径
2、初始化画笔,圆角主要是setStrokeCap(Cap.ROUND)来设置的,而设置抖动setDither()这个大概意思是保证画图的清晰度已经平滑度,抗锯齿setAntiAlias();表示画出来的视图不会有锯齿
二、再来看看其onMeasure和onDraw()方法:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 两个画笔的最大宽度 int paintWidth = Math.max(mUnReachBarWidth, mReachBarWidth); int wMode = MeasureSpec.getMode(widthMeasureSpec); int wSize = MeasureSpec.getSize(widthMeasureSpec); int hMode = MeasureSpec.getMode(heightMeasureSpec); int hSize = MeasureSpec.getSize(heightMeasureSpec); if (wMode == MeasureSpec.AT_MOST && hMode == MeasureSpec.AT_MOST) { wSize = mRadius * 2 + (paintWidth / 2) * 2; hSize = mRadius * 2 + (paintWidth / 2) * 2; } else if (wMode == MeasureSpec.AT_MOST) { wSize = mRadius * 2 + (paintWidth / 2) * 2; } else if (hMode == MeasureSpec.AT_MOST) { hSize = mRadius * 2 + (paintWidth / 2) * 2; } if (0 >= wSize) { wSize = mRadius * 2; } if (0 >= hSize) { hSize = mRadius * 2; } // 获取宽度和高度的最小值,作为当前view的宽度和高度 mSize = Math.min(wSize, hSize); // 设置进度条的大小:整个view的大小 setMeasuredDimension(mSize, mSize); // 设置画笔宽度 mMaxPaintWidth = paintWidth; // 计算进度条的半径 画笔是从画笔的宽度中间开始画的---- // 、、此处有个坑,若是有进入到二级页面再回来,可能视图会变小,因为每次半径测量时都会减小, // 根据需要半径最好放在初始化时设置,不要让它变化 mRadius = (mSize - (mMaxPaintWidth / 2) * 2) / 2; mPaint.setStrokeWidth(mMaxPaintWidth); mPaintUnReach.setStrokeWidth(mMaxPaintWidth); }
@Override protected void onDraw(Canvas canvas) { // 在save和restore之间的代码可以进行canvas的平移、缩放等操作 canvas.save(); // 画布旋转120度 canvas.rotate(115, mSize / 2, mSize / 2); int progressMax = getMax(); // 绘制unreachedBar // 绘制reachBar :画布旋转115度,所以是从115度开始,从0开始,从 5度开始画,就是120 canvas.drawArc(new RectF(mMaxPaintWidth / 2, mMaxPaintWidth / 2, mSize - mMaxPaintWidth / 2, mSize - mMaxPaintWidth / 2), 5, progressMax * 1.0f / progressMax * 300, false, mPaintUnReach); // canvas.drawCircle(mSize / 2, mSize / 2, mRadius, mPaintUnReach); // 设置画笔颜色:绘制过程中会渐变 mReachBarColor是数组起始颜色和最终颜色,渐变的过程 SweepGradient sg = new SweepGradient(mSize / 2, mSize / 2, mReachBarColor, null); mPaint.setShader(sg); // sg.setLocalMatrix();除了旋转画布外,也可根据这个矩阵来旋转起始角度 // 计算当前进度对应的角度 float sweepAngle = mCurrentProgress * 1.0f / progressMax * 300; // 绘制reachBar :原始0度角是沿x轴方向的旋转115度之后,0角度指的就是115度的位置, // 起始角度为5是因为画弧度的颜色值是从一半开始画的,所以后一半圆会取前边的颜色值,导致不一致,所以从5度开始画,可根据画笔宽度的一半来设置 canvas.drawArc(new RectF(mMaxPaintWidth / 2, mMaxPaintWidth / 2, mSize - mMaxPaintWidth / 2, mSize - mMaxPaintWidth / 2), 5, sweepAngle, false, mPaint); canvas.restore(); drawText(canvas); } private void drawText(Canvas canvas) { mTextPaint.setColor(Color.WHITE); mTextPaint.setTextSize(dp2px(40)); mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);// 设置粗体 float weightWidth = mTextPaint.measureText(weightValue); float weightTextSize = mTextPaint.getTextSize(); canvas.drawText(weightValue, mSize / 2 - weightWidth / 2, mSize / 2 + weightTextSize / 2 - dp2px(5), mTextPaint); mTextPaint.setTypeface(Typeface.DEFAULT);//设置常规字体 // 绘制单位(Kg) mTextPaint.setTextSize(dp2px(12)); // 此处多减去了一个textSize的一半,因为绘制text的时候 canvas.drawText(unit, mSize / 2 + weightWidth / 2, mSize / 2 + weightTextSize / 2 - dp2px(5), mTextPaint); // 绘制“体重状态” mTextPaint.setTextSize(dp2px(12)); weightWidth = mTextPaint.measureText(weightStatus); // 以下也可以获取大小范围 // mPaint.getTextBounds(text, 0, text.length(), mRect);// // int x = (getWidth() / 2) - mRect.centerX();// 文本的内容区域中心点开始绘制 // int y = (getHeight() / 2) - mRect.centerY(); float weightStatusTextSize = mTextPaint.getTextSize(); canvas.drawText(weightStatus, mSize / 2 - weightWidth / 2, mSize / 2 - dp2px(12) - weightTextSize / 2, mTextPaint); // 绘制“体重目标” mTextPaint.setTextSize(dp2px(12)); weightWidth = mTextPaint.measureText(weightTargetDesc); float targetTextSize = mTextPaint.getTextSize(); canvas.drawText(weightTargetDesc, mSize / 2 - weightWidth / 2, mSize / 2 + weightTextSize, mTextPaint); }
1、主要是测量视图的宽高,然后通过setMeasuredimension来设置其测量的宽高
高能预警:此处有个坑,天大的坑 :mRadius 在这里不断的赋值,由于onMeasure不单单执行一次,在测量期间会执行多次,导致mRadius一直在变化,导致逐渐变小或变大,导致视图可能会变的更大或视图不可见,所以这种初始化的赋值,建议放在初始化或ondraw中,就不会有这种问题。。。这里出现问题就直接拿出来跟大家分享,代码我也没改正,圆角渐变代码我并没有改正,但是色环的已经改正了,代码都差不多,自行参考
2、onDraw方法中 首先因为起始角度(0角度)是x轴方向,所以要旋转画布到自己所需要的开始绘制的地方,这里将画布旋转115,即绘制的起始点;此外由于画笔是从画笔的宽度中心点开始绘制的所以mRadius半径mSize减去画笔跨度的一半再除以2,就是画圆的半径 即(
mRadius = (mSize - (mMaxPaintWidth / 2) * 2) / 2
,而后drawArc就是画弧,第一次调用就是画弧的背景,第二次才是画弧的进度,画弧的时候起始角度是从5开始,因为,画笔是从中间开始的,而由于是渐变色(SweepGradent类控制的)前一半圆弧的颜色是往前取的所以会导致有色差,所以起始角度往后一移动5个角度(可根据画笔宽度的一半来取),这也是为什么只旋转115而不是120角度的原因。
二、色环的代码跟圆弧的差不多,依葫芦画瓢,相信读者都有举一反三的能力,这里就不再讲解,需要的可下载demo查看源码
demo:http://download.csdn.net/detail/zhongwn/9531575
相关文章推荐
- iOS 颜色渐变圆环
- STM32七彩色带
- Android - Ashmem驱动
- Android实现毛玻璃效果
- Android识别图片中脸部信息
- Android adb命令与操作
- Android开发中常见的设计模式
- Android onActivityResult获取返回值的用法
- Android studio设置logcat缓存的方法
- Android笔记之沉浸式状态栏
- Android Studio 查看类结构和继承关系
- Android 6.0 Runtime Permissions运行权限学习笔记
- adb连接Android手机
- 使用Fresco时 so 报错分析及解决方案
- android 开发相机焦距解析之调节远近焦距
- VS2015 Android SDK 下载和更新失败的解决方法
- android游戏初步 01 游戏框架
- Android CheckBox的OnCheckedChangeListener监听传值
- Android-TextView设置行间距与行高。
- Android基础