自定义view(结合刻度盘学习)
先上效果图

一、View的测量(刻度盘的大小测量)
在现实生活中,我们如果要去画一个图形,那么便要知道它的大小和位置。所以android绘图时需要我们对view进行测量。android为我们提供了onMeasure()方法来帮助我们去测量一个view,我们只需要重写onMeasur()方法,将我们测算长宽设置给setMeasuredDimension()。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//根据模式测算长宽
... setMeasuredDimension(width,height);
}
我们首先测量我们最开始弧形的大小。即图中的样例。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//根据模式测算长宽,这里获取的尺寸便是在xml文件中指定的尺寸
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
//以最小值为刻度区域正方形的长
len = Math.min(width, height);
//确定圆弧所在的矩形区域
oval = new RectF(0, 0, len, len);
radius = len/2;
//设置测量高度和宽度
setMeasuredDimension(len,len);
}
二、View的绘制(简单绘制出我们需要的弧形)
测算完成后我们需要将他在画面上显示出来,android为我们提供了onDraw()方法,来绘制view。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//弧形的绘画查看api
canvas.drawArc(oval,startAngle,sweepAngle,useCenter,paint); }
不了解canvas的可以去看看canvas的绘制API
现在在布局文件中设置后,就可以看见我们最开始的view了。

三、完善我们的绘制,为仪表盘添加刻度。
private void drawViewLine(Canvas canvas) {
canvas.save();
//移动canvas
canvas.translate(radius,radius);
//旋转canvas
canvas.rotate(30);
//普通刻度
Paint linePatin=new Paint();
//设置普通刻度画笔颜色
linePatin.setColor(Color.WHITE);
//线宽
linePatin.setStrokeWidth(2);
//设置画笔抗锯齿
linePatin.setAntiAlias(true);
/* //画一条刻度线
canvas.drawLine(0,radius,0,radius-40,linePatin);*/
//画101条刻度线
//确定每次旋转的角度
float rotateAngle=sweepAngle/99;
//绘制需要有颜色部分的画笔
Paint targetLinePatin=new Paint();
targetLinePatin.setColor(Color.GREEN);
targetLinePatin.setStrokeWidth(2);
targetLinePatin.setAntiAlias(true);
//记录已经绘制过的有色部分范围(角度float)
float hasDraw=0;
for(int i=0;i<100;i++){
if (hasDraw <= targetAngle && targetAngle != 0) {
//计算已经绘制的比例
canvas.drawLine(0, radius, 0, radius - 40, targetLinePatin);
} else {
canvas.drawLine(0,radius,0,radius-40,linePatin);
}
hasDraw += rotateAngle;
canvas.rotate(rotateAngle);
}
//操作完成后恢复状态
canvas.restore();
}
如图

四、完善onMeasure()测量
我们先看看在布局中的CircleView
原先
<com.example.tyr.circleviewtest.CircleView
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
如图


改成Button
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
现在,我么修改CircleView改为wrap_content,如图
可以发现没有改变
对比button的wrap_content可以发现如图,


所以我们需要在onMeasure()方法中,对view的模式进行区别测量。
五、MeasureSpec类
android系统为我们提供了一个短小精悍的类MeasureSpec。它是一个32位的int值,高两位为测量模式,低30位为测量大小。
测量模式分为三种:
1、EXACTLY--系统的默认模式。
精确模式,当我们将width和height指定100dp、200dp等精确值时或是match_parent属性时系统使用EXACTLY模式
2、AT_MOST
最大值模式,当height和width属性指定为wrap_content时,控件大小随子控件或内容的变化而变化,控件大小只要不超过父控件允许的最大尺寸即可。
3、UNSPECIFIED
不指定大小测量模式,view想多大就多大,通常在绘制自定义view时才会用。
将onMeasure()方法进行修改,适应wrap_content
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//根据模式测算长宽
int width = measureSize(widthMeasureSpec);
int height = measureSize(heightMeasureSpec);
//以最小值为刻度区域正方形的长
len = Math.min(width, height);
//确定圆弧所在的矩形区域
oval = new RectF(0, 0, len, len);
radius = len/2;
//设置测量高度和宽度
setMeasuredDimension(len, len);
} private int measureSize(int measureSpec){
//差不多固定的格式
int reslut = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode==MeasureSpec.EXACTLY){
reslut = specSize;
}else{
reslut = 200;
if (specMode==MeasureSpec.AT_MOST){
reslut = Math.min(reslut,specSize);
}
} return reslut;
}

六、自定义属性
我们在xml文件中使用的时候往往会使用一些属性类似width和height等等,那么我们便需要为我们的刻度盘添加新的属性。
<resources>
<declare-styleable name="CircleView">
<attr name="pointDisArc" format="dimension"></attr>
<attr name="textSize" format="dimension"></attr>
</declare-styleable>
</resources>
在构造方法中处理
public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
parseAttr(context, attrs, defStyleAttr);
initPaint();
}
private void parseAttr(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.CircleView,defStyleAttr,0);
pDisArc = typedArray.getDimensionPixelSize(R.styleable.CircleView_pointDisArc,dp2px(context,20));
textSize = typedArray.getDimensionPixelSize(R.styleable.CircleView_textSize,dp2px(context,20));
typedArray.recycle();
}
<com.example.tyr.circleviewtest.CircleView
android:id="@+id/cicleview"
android:layout_width="match_parent"
android:layout_height="match_parent"
circle:textSize="20sp"
circle:pointDisArc="20dp"
/>
到目前为止view的自定义差不多完成了,也可以将刻度盘设计的更加精巧一些,下一节开始viewgroup的绘制,涉及到新的方法onLayout()。
自定义view(结合刻度盘学习)的更多相关文章
- Android自定义View初步
经过上一篇的介绍,大家对于自定义View一定有了一定的认识,接下来我们就以实现一个图片下显示文字的自定义View来练习一下.废话不多说,下面进入我们的正题,首先看一下我们的思路,1.我们需要通过在va ...
- 通过圆形载入View了解自定义View
这是自定义View的第一篇文章,通过制作简单的自定义View来了解自定义View的流程. 自定义View是Android学习和开发中必不可少的一部分.通过自定义View我们可以制作丰富绚丽的控件,自定 ...
- Android查缺补漏(View篇)--自定义 View 的基本流程
View是Android很重要的一部分,常用的View有Button.TextView.EditView.ListView.GridView.各种layout等等,开发者通过对这些View的各种组合以 ...
- 简单说说Android自定义view学习推荐的方式
这几天比较受关注,挺开心的,嘿嘿. 这里给大家总结一下学习自定义view的一些技巧. 以后写自定义view可能不会写博客了,但是可以开源的我会把源码丢到github上我的地址:https://git ...
- 20170831工作日记--自定义View学习
学习了LayoutInflater的原理分析.视图的绘制流程.视图的状态及重绘等知识,按类型来划分的话,自定义View的实现方式大概可以分为三种,自绘控件.组合控件.以及继承控件.那么下面我们就来依次 ...
- Android之自定义View学习(一)
Android之自定义View学习(一) Canvas常用方法: 图片来源 /** * Created by SiberiaDante on 2017/6/3. */ public class Bas ...
- Android开发之制作圆形头像自定义View,直接引用工具类,加快开发速度。带有源代码学习
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 QQ986945193 博客园主页:http://www.cnblogs.com/mcxiaobing ...
- salesforce 零基础学习(五十)自定义View或者List以及查看系统原来的View或者List
salesforce给我们提供了标准的页面,比如标准的页面包括标准的列表和标准的详细页视图.有的时候我们想要自定义视图,比如做一个项目的时候不希望使用者直接通过ID查看到标准的详细页,而是跳转到指定处 ...
- Android自定义View学习(四)
硬件加速 参考:HenCoder Android 自定义 View 1-8 硬件加速 硬件加速能够让绘制变快,主要有三个原因: 本来由 CPU 自己来做的事,分摊给了 GPU 一部分,自然可以提高效率 ...
随机推荐
- laravel开发之-(1)数据库链接测试
composer安装成功后,网站建设的操作记录: 一.修改默认首页.伪静态配置文件 1.将serve.php改为index.php 2.public文件夹下的.htaccess文件复制到根目录下 二. ...
- px、em、pt之间的区别与互相转换
关于px.pt和em的区别,自己有时候也会纠结到底该用什么单位,今天特意查了一些文章,下面这篇虽然很久远了,但解释的比较全面,转载收藏之.点击查看原文(原网址已失效,这是其他站点) 这里引用的是Jor ...
- 关于webpack 配置文件找不到
运行命令 npm run eject 将配置文件解压出来 如果运行这个命令有错的时候,很可能与 git 有关 这时候,打开项目文件夹,显示所有隐藏的文件夹(工具),如果显示了git 的文件夹 删掉 ...
- MathQuill.js
MathQuill.js通过html.css.javascript实现数学公式 <p>Type math here: <span id="math-field"& ...
- 阿里,百度,腾讯招聘 Java 程序员的技术标准
阿里巴巴篇 扎实的计算机专业基础,包括算法和数据结构,操作系统,计算机网络,计算机体系结构,数据库等 具有扎实的Java编程基础,理解IO.多线程等基础框架 熟练使用Linux系统的常用命令及shel ...
- Ubuntu 安装 PhpMyAdmin 图文教程
Ubuntu 安装 PhpMyAdmin 管理 MySQL 数据库 PhpMyAdmin 是一个用 PHP 编写的软件工具,可以通过 web方式控制和操作 MySQL 数据库.通过 phpMyAdmi ...
- Angular1.x 之Providers (Value, Factory, Service and Constant )
官方文档Providers Each web application you build is composed of objects that collaborate to get stuff do ...
- centos虚拟机网卡配置
连接模式为NAT
- spring cloud config配置
参考: http://www.ityouknow.com/springcloud/2017/05/22/springcloud-config-git.html http://www.ityouknow ...
- 如何写自定义的AlertView
如何写自定义的AlertView 效果 说明 考虑到后面的可定制性以及可维护性,本人用AbstractAlertView定义了AlertView抽象的基类,实现通过子类来完成. 注:这只是粗略的写了一 ...