您的位置:首页 > 移动开发 > Android开发

Android 仪表进度条 自定义View

2016-11-01 15:39 197 查看

Android 自定义仪表进度条浅析

最近写了几个小教程,一次性发出来吧,今天最后一篇,继续玩一玩自定义View吧,这次加上了自定义属性,即,在xml中引用该控件可以通过自定义属性设置一些效果。该进度条实现了颜色渐变等,是出门旅行,熟悉自定义View之必备补品,可直接用于实际项目,已优化,比如下载东西展示个进度什么的,知识点掌握之后,你想怎么折腾就怎么折腾吧。

(Gradle Build)

原创帖,转载请注明出处,开源思想,欢迎关注探讨Github:https://github.com/Zjinji/MeterView

作者:尽际

目录

Android 自定义仪表进度条浅析
目录

学习流程
基础知识

绘制技巧

Have Fun附上截图

学习流程:

基础知识

绘制技巧

Have fun

基础知识

1、Canvas旋转
a、baseCanvas.rotate(1, 2, 3);
参数1:画布旋转角度,负数为逆时针,正数为顺时针
参数2:旋转围绕的中心x坐标
参数3:旋转围绕的中心y坐标
2、attrs定义
a、在values文件夹中,创建attrs.xml文件,文件内容大致如下,
主要是定义一些后续会使用到的属性:


<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MeterView">
<attr name="arcColor" format="color"/>
<attr name="arcWidth" format="dimension"/>
<
4000
attr name="text" format="string"/>
<attr name="levelCount" format="integer"/>
<attr name="innerCircleColor" format="color"/>
<attr name="pointerColor" format="color"/>
<attr name="textSize" format="dimension"/>
</declare-styleable>
</resources>


3、TypedArray
a、在自定义View的构造方法中,通过该对象得到引用资源,即


TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MeterView, defStyleAttr, 0);


b、
参数1:attrsSet集合
参数2:你刚才定义的declare-styleable
参数3:默认样式
这个默认样式为如果用户没有显示的在xml中使用你刚才的属性,那么这些属性的默认值是多少,你可以自己设定一下,比如:


<style name="MeterViewInStyle">
<item name="arcColor">#0085cc</item>
<item name="levelCount">12</item>
<item name="innerCircleColor">#939393</item>
<item name="pointerColor">#4d4d4d</item>
<item name="textSize">24px</item>
<item name="text">当前速度</item>
<item name="arcWidth">50px</item>
</style>


参数4:还是默认样式。此处详情请查阅:obtainStyledAttributes
方法的源码注释。

4、canvas save restore
a、save:即保存画布的当前状态,这个状态是指画布的位置状态,很多人会理解为画布当前画了哪些东西的状态,这种思想很危险。:)
b、restore:即恢复画布到刚才保存的状态节点。
一般在save以及restore中间会做一些基本的操作,比如在一个圆上绘制刻度,通过旋转画布的方式比用三角函数更轻松些。
详情见代码,一看便知,注释详细。
5、onMessure
a、View的测量,自定义View方法的调用顺序为:
onMessure 测量
onLayout 布局
onDraw 绘制
在绘制之前,可能会多次的调用测量和布局方法。其中
onMessure中的具体实现,见代码,主要用户就是来确定
当前空间的大小。
(Paint此处先不赘述了)


绘制技巧

1、避免在onDraw方法中实例化对象,底层仪表不论进度怎么变化,仪表都是没有变化的;
所以,仪表应该当做底层图层来绘制;
最后在onDraw中直接绘制整个仪表图层即可,变化的部分,直接放在onDraw中绘制。如果你能有PS中作图时图层的感觉就好。
底层图层这样做:


baseBitmap = Bitmap.createBitmap(meterViewWidth, meterViewHeight, Bitmap.Config.ARGB_8888);
baseCanvas = new Canvas(baseBitmap);


2、画弧
a、确定圆弧的绘制区域RectF outterArc = new RectF(1, 2, 3, 4)
参数1,2:矩形左上角顶点坐标
参数3,4:矩形右下角顶点坐标
b、baseCanvas.drawArc(1, 2, 3, 4, 5);
参数1:你刚才定义的矩形区域
参数2:圆弧起始角度,圆心右方水平为0°,顺时针递增,大家脑补下。
参数3:圆弧扫过角度。即,从参数2顺时针,扫多少个角度。
参数4:是否将圆弧两端顶点连接并填充颜色,需要配合画笔(FILL style)
参数5:画笔对象
(注:顺时针为正角度,逆时针为负角度)
c、绘制刻度:通过画布旋转


//绘制右边刻度
//旋转角度
float roundAngle = 250f / levelCount;
//右刻度
//当画布进行任何位置变换后,最终均将回到最初状态
baseCanvas.save();
for(int i = 0; i < levelCount / 2; i++){
baseCanvas.rotate(roundAngle, w / 2, h / 2);
baseCanvas.drawLine(w / 2, 0, w / 2, 20, basePaint);
}
baseCanvas.restore();


旋转画布绘制刻度怎么理解呢,你可以想象成,画笔不动(即绘制坐标不变),让画布转圈,这样子,画笔就可以在画布的不同位置绘制内容了。

以上为绘制重点,其他,比如设置个什么百分比了,动态改变当前进度了,就很简答了,代码见就好。
渐变效果,是为画笔设置了LinearGradient线性渐变Shader。即:paint.setShader(linearGradient);
(如果没有格式错误的话,在代码204行)


Have Fun(附上截图)

因为对于你们过于简单,核心讲解完了,没啥好说了感觉。
大家玩的开心:)




源码传送门:免积分分享给大家

[自定义仪表MeterView]http://download.csdn.net/detail/z279868688/9669182

PS:Github以及这里会持续更新Android有趣的开发。欢迎关注探讨。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐