讲真,自我感觉,我的水平真的是渣的一匹,好多东西都只停留在知道和会用的阶段,也想去研究原理和底层的实现,可是一看到代码就懵逼了,然后就看不下去了,

说自己不着急都是骗人的,我自己都不信,前两天买了本《Android 群英传》,江湖上都说这是一本初级过渡到中级不错的进阶书,所以准备看一下,才看了两天,今天

看到了view的测量及绘制,还有自定义view(还没看完),学到什么就写篇博客吧,算是对自己所学的一个总结和记录吧,也可以督促自己,如果有讲的不对的地方或者

有歧义的地方,欢迎大家吐槽批评我!

  转载请注明出处:Android view的测量及绘制

  正文开始(手动鼓掌)

  view的测量:

  首先需要知道的是view的三种测量模式:

  1、EXACTLY:精确值模式,当我们对view的layout_width和layout_height属性指定具体的数值的时候,比如layout_width=“100dp”或者指定为match_parent时,系统

进行测量的时候,使用的是这种模式。

  2、AT_MOST:最大值模式,当我们对view的layout_width和layout_height属性指定为wrap_content时,即view随着内容的大小变化而变化,或viewgroup随着view的

大小变化而变化,这个时候系统进行测量的时候,使用的是这种模式。

  3、UNSPECIFIED:这个属性下不用指定其大小,一般在自定义view时才会使用(这种模式不是很理解,求指教)

  在对view进行测量的时候,需要重写onMeasure()方法,view默认的onMeasure()方法只支持EXACTLY模式,即指定具体的数值,所以在自定义view的时候必须重写

onMeasure(),这里留一个疑问:什么时候才会调用Measure方法进行测量?

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

  重写后点super.onMeasure(widthMeasureSpec, heightMeasureSpec);进去看一下源码,发现系统最终会调用这个方法:

setMeasuredDimension(int widthMeasureSpec,int heightMeasureSpec);

这个方法的作用是将我们对view设置的宽和高设置进去,所以我们最终重写的onMeasure()方法就是这个样子的,方法内的两个入参widthMeasureSpec和heightMeasureSpec

就是我们在xml里引用这个view时设置的width和height,后面我们需要根据这两个值进行判断,判断系统要根据什么测量模式进行测量。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec));
}

  前文一直在说系统的测量模式,那么我们要怎么样才能获取到系统的测量模式呢?获取测量模式后还需要获取具体的测量大小

int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);

  单独对measureWidth(widthMeasureSpec)讲解一下,因为height和width是一样的。

    private int measureWidth(int widthMeasureSpec) {
int widthResult = ;
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);
if (specMode == MeasureSpec.EXACTLY){
widthResult = specSize;
}else {
widthResult = ;
if (specMode == MeasureSpec.AT_MOST){
widthResult = Math.min(widthResult,specSize);
}
}
return widthResult;
}

  这部分的理解要联系到前面说的3种测量模式,如果是在EXACTLY if (specMode == MeasureSpec.EXACTLY) 这种模式下,我们已经在xml里面设置好了具体的数值,所以最后返回的值就是specSize

如果是AT_MOST和UNSPECIFIED这两种测量模式下,我们就需要给view一个默认的大小,因为如果没有给默认的大小的话,系统不知道view的大小,所以view或默认充满父布局。这里默认的大小是400,

大家会发现else里面还有一个if,对AT_MOST这种模式又进行了判断,这是因为在这种模式下,view不需要默认的大小,view的是根据内容的大小变换而变化的。

最后就是xml里面进行引用和效果展示了:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.funny.myapplication.MainActivity"> <com.funny.myapplication.StudyView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View"
android:textSize="20sp"
android:background="#ccf"
android:gravity="center"/>
</RelativeLayout>

(1)android:layout_width="wrap_content"

(2)android:layout_width="match_parent"

(3)android:layout_width="400px"

  view的绘制:

  对view进行绘制需要重写onDraw()方法,onDraw()方法中会有一个canvas,可以把这个参数理解成画板,我们最终会借用这个画板进行绘制。

有了画板,要想绘画的话当然还需要一支画笔paint。

    @Override
protected void onDraw(Canvas canvas) {
Paint paint1 = new Paint();
paint1.setColor(getResources().getColor(R.color.colorAccent));
paint1.setStyle(Paint.Style.FILL);
Paint paint2 = new Paint();
paint2.setColor(getResources().getColor(R.color.colorPrimary));
paint2.setStyle(Paint.Style.FILL);
     //开始绘制
canvas.drawOval(,,getMeasuredWidth(),getMeasuredHeight(),paint1);
canvas.drawOval(,,getMeasuredWidth()-,getMeasuredHeight()-,paint2);
     //平移30个像素
canvas.translate(, );
super.onDraw(canvas);
canvas.restore();
}

  接下讲解一下这段代码的功能,首先实例了两只画笔,并且对画笔设置了颜色和风格,接下来开始绘制,这里我们画的是两个相互嵌套的椭圆,

canvas.drawOval(0,0,getMeasuredWidth(),getMeasuredHeight(),paint1);这个方法需要5个入参,分别是view相对于父布局的左、上、右、下的坐标,最后一个是进行绘制的画笔。

  系统给我们提供的drawXXX方法有很多:

canvas绘制的常用方法有:
drawColor() 填充颜色
drawLine() 绘制线
drawLines() 绘制线条
drawOval() 绘制圆
drawPath() 绘制路径
drawPicture() 绘制图片
drawPoint() 绘制点
drawPoints() 绘制点
drawRGB() 填充颜色
drawRect() 绘制矩形
drawText() 绘制文本
drawTextOnPath() 在路径上绘制文本

效果展示:

  viewGroup的测量:

  我们知道viewGroup管理子view,那么viewGroup的大小,除设置指定大小外,是根据子view来决定的,viewGroup在测量时会遍历所有的子view,调用

子view的Measure方法来获得每一个子view的测量结果,这样文章开始留下的疑问就解决了,意不意外~关于viewGroup的绘制,一般情况下如果不是指定

了viewGroup的背景颜色,viewGroup的onDraw()方法不会被调用,但是viewGroup会使用dispatchDraw()方法来绘制其子view,过程同样是遍历所有的子view

,并调用子view的绘制方法来完成绘制。

  以上就是我对view的测量及绘制的全部理解,可能在很多人看来还是处于初级阶段,没有怎么涉及到源码,但是还是希望能帮助到一些人吧,对我自己也是一点点进步嘛,如果大家有什么

好的理解,欢迎留言哈~~~酱!拜啦!

Android view的测量及绘制的更多相关文章

  1. android View的测量和绘制

    本篇内容来源于android 群英传(徐易生著) 我写到这里,是觉得徐易生讲的确实很好, 另外加入了一些自己的理解,便于自己基础的提高. 另外参考:http://www.gcssloop.com/cu ...

  2. Android View 如何测量

    对于Android View的测量,我们一句话总结为:"给我位置和大小,我就知道您长到那里". 为了让大家更好的理解这个结论,我这里先讲一个日常生活中的小故事:不知道大家玩过&qu ...

  3. 【转载】快速理解android View的测量onMeasure()与MeasureSpec

    笔者之前有一篇文章已经使用onMeasure()解决了listview与scollview的显示冲突问题,博客地址如下: onMeasure简单方法 完美解决ListView与ScollView冲突问 ...

  4. 自定义View_1_关于View,ViewGroup的测量和绘制流程

    自定义View(1) ------ 关于View,ViewGroup的测量和绘制流程 在Android当中,自定义控件属于比较高级的知识体系,今天我们就一起研究研究关于自定义View的那点事,看看它到 ...

  5. Android View框架总结(三)View工作原理

    转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52180375 测量/布局/绘制顺序 如何引起View的测量/布局/绘制? Perfor ...

  6. 【原创】Android View框架总结(三)View工作原理

    测量/布局/绘制顺序 如何引起View的测量/布局/绘制? PerformTraversales() ViewRoot View工作基本流程  MeasureSpec SpecMode Measure ...

  7. [译]Android view 测量布局和绘制的流程

    原文链接 创造优秀的用户体验是我们开发者的主要目标之一.为此, 我们首先要了解系统是如何工作的, 这样我们才可以更好的与系统配合, 从它的优点中获益, 规避它的缺陷. 之前关于Android渲染过程的 ...

  8. Android View的绘制流程

    写得太好了,本来还想自己写的,奈何肚里墨水有限,直接转吧.正所谓前人种树,后人乘凉.. View的绘制和事件处理是两个重要的主题,上一篇<图解 Android事件分发机制>已经把事件的分发 ...

  9. 简单研究Android View绘制三 布局过程

    2015-07-28 17:29:19 这一篇主要看看布局过程 一.布局过程肯定要不可避免的涉及到layout()和onLayout()方法,这两个方法都是定义在View.java中,源码如下: /* ...

随机推荐

  1. java环境安装之不能安装exe文件

    经过多年,打算再学下java 从官网下载java8安装包,但因为我的计算机的cd-room被卸载掉了,安装是报错说cab文件损坏之类的错误. 从stackOverflow中找到一篇眼前一亮的解决办法. ...

  2. CentOS6.5_x86安装Mysql5.5.49

    1.说明: 安装MySQL主要有两种方法:一种是通过源码自行编译安装,这种适合高级用户定制MySQL的特性,这里不做说明:另一种是通过编译过的二进制文件进行安装.二进制文件安装的方法又分为两种:一种是 ...

  3. Python数据类型和变量

    一.数据类型1.整型整型类型比较简单,就是我们数学中的正整数(1,2,520..).负整数(-2,-9..);与java不同的是,python中的整数可以无限大,而java的整数类型int为四个字节, ...

  4. 搜索技术---solr

    solr 企业站内搜索技术选型 在一些大型门户网站.电子商务网站等都需要站内搜索功能,使用传统的数据库查询方式实现搜索无法满足一些高级的搜索需求,比如:搜索速度要快.搜索结果按相关度排序.搜索内容格式 ...

  5. POJ2524并查集水题

    Description There are so many different religions in the world today that it is difficult to keep tr ...

  6. 小程序的1024KB

    1024kb 只是一个目前编译后代码可上传最大限制,至于后期会不会更改,不得而知.个人只是想借 1024kb 来和大家一起交流一下,如何在限制下,挥舞大刀- 微信官方回答了,为什么有 1024kb 的 ...

  7. 一个html页面传入参数到另一个html页面用js获取方法

    没错使用以下函数就能够完整的获取到路径里的你想要的参数:function getURLParameter(name) { return decodeURIComponent((new RegExp(' ...

  8. 自研框架wap.js实践

    示例 使用分为3个步骤: 1, 配置模板渲染中心,方便别人可以看到你的模板渲染,请求是什么关系,复杂度怎样 2, 配置事件分发中心  方便观察事件分发,事件复杂度 3,写对应的请求方法.渲染方法.   ...

  9. 一、Openstack_Ocata环境部署准备

    OpenStack Ocata环境搭建准备 1.workstation下配置3个虚拟交换机 点击编辑-->虚拟网络编辑器 名称 IP地址 作用 VMnet1 10.1.1.0 Openstack ...

  10. 天气正好,hello world!

    两个多月,稀里糊涂的回来了,内心很迷茫,回来一周了,明知道还需要有一大堆东西需要去学,但是却找不到之前学习的状态,在寝室,在实验室,看着自己一向不喜欢的电视剧,无目的的逛着淘宝,刷着头条和知乎,就这么 ...