《Android群英传》读书笔记——Android控件架构

《Android群英传》读书笔记

最近在找工作。。。话说北京这个时候的工作真不好找啊。。。慢慢来吧,总会找到的,最近在拜读一本大作,叫做《Android群英传》是大神写的。是一本好书。这本书讲了很多的高级的知识,真是太牛X了。今天看了这本书的Android控件架构与自定义控件,做一个读书笔记

Android控件架构

Android中的每一个控件都在界面中占得一块矩形的区域,在Android中控件分为两类: 
ViewGroup:作为父控件其包含很多的子控件。并管理其包含的View控件。ViewGroup使得整个界面上的控件形成了一个树形结构——控件树,上层的控件负责下层子控件的测量和绘制。并传递交互事件。使用findViewbyId()就是在控件树中以树的深度优先遍历来查找对应元素 
View控件就是包含在父控件下的控件。由父控件来管理

分析setContentView()

每个Activity包含一个Window对象,Window对象通常由PhoneWindow来实现。PhoneView将一个DecorView作为应用窗口的根View.(顶层视图),并封装了一些窗口操作的通用方法。DecorView将要显示的内容呈现在了phoneWindow上,所有的View的监听事件,都通过WindowManagerService来接受。并通过Activity对象来回调相应的onClicklistener. 
在显示上,界面分为两部分 一个是TitleView 一个是ContentView。ContentView是一个ID为Content的Framelayout,我们的Activity布局文件就是设置在这样一个Framelayout中。 
再显示界面中也就是DecorView中装载了一个线性布局。我们最常用的布局比如上面显示一个TitleBar 下面是Content的布局就是作为线性布局显示在界面上的。这里也能说明如果我们要设置全屏的话为什么requestWindowFeature(WindowFEATURENOTITLE)要设置在setContentView()前面。 
在代码中,当程序在onCreate()方法中调用setContentView()方法后,ActivityManagerService会回调onResume()方法,此时系统才会把整个DecorView添加到PhoneWindow中并让其显示。完成绘制也就是说系统完成界面的绘制是在onResume()方法中完成的。

自定义View

ViewGroup测量

ViewGroup会管理其子View,其中一个管理项目就是管理子View的显示大小。ViewGroup的大小为wrap_content时,ViewGroup就需要对子View进行遍历。可以获得所有子View的大小。 
ViewGroup在测量时通过遍历所有子View,从而调用子View的Measure方法来获得每一个子View的测量结果

View的布局

子View测量完毕后,需要将子View放到合适的位置,这时就会调用View的Layout过程。ViewGroup在执行Layout过程时,会同时遍历来调用子View的Layout方法。并指定具体显示位置。

View的测量

Android在绘制View前,必须对View进行测量,以确定显示的大小。测量的过程在onMeasure()方法中进行 
Android提供了一个MeasureSpec类,来帮助我们测量View.MeasureSpec是一个32位的int值。其中高2位为测量的模式,后面的为测量的大小。(为提高效率使用位运算) 
测量的模式:

EXACTLY:

当我们使用精确值模式,指定大小或者match_parent时,系统使用的是EXACTLY

AT_MOST:

最大值模式,当我们使用wrap_content时,要求此时控件的尺寸只要不超过父控件允许的最大尺寸即可

UNSPECIFIED:

绘制自定义View的时候使用,不指定大小

View默认的onMeasure()方法只支持EXACTLY模式,如果自定义控件不写onMeasure()方法的时候,就只能使用EXACTLY模式。 
如果你想控件可以响应指定的具体值或者是matchparent属性,可以不重写onMeasure()方法 
如果控件不指定大小 wrap
content时就必须要重写onMeasure()方法 
通过MeasureSpec这个类,我们可以获取View的测量模式和想要绘制的大小 
我们可以从MeasureSpec对象中取出测量的模式和测量值的大小

    int mode = MeasureSpec.getMode(widthMeasureSpec);
    int size = MeasureSpec.getSize(widthMeasureSpec);

通过判断测量的模式,可以得出不同的测量值

  • 当SpecMode为EXACTLY模式: 
    直接使用指定的specSize即可
  • 其它两种模式时: 
    需要给它一个默认的大小
  • ATMOST模式: 想要支持wrapcontent 需要取出我们指定的大小与specSize中最小的一个来作为最后的测量值

View绘制

测量好View后,就可以重写onDraw()方法,并在Canvas上绘制所需要的图形

绘制所需要的Canvas对象

要想绘制相应的图像,就必须在Canvas上绘制 onDraw()中有一个参数就是Canvas canvas对象 使用这个Canvas对象就可以进行绘图 创建一个Canvas对象时候需要传进去一个Bitmap对象,这样你调用所有的Canvas对象的drawXXX方法都将发生在这个bitmap上

自定义View

View中的重要的回调方法
  • onFinishInflate() xml加载组件后回调
  • onSizeChanged() 组件大小改变时回调
  • onMeasure() 回调该方法来进行测量
  • onLayout()回调该方法来确定显示的位置
  • onTouchEvent 监听到触摸事件的回调

自定义View的方式

对现有组件扩展

继承现有的组件,添加自己的功能 onDraw()方法

创建复合控件

继承一个ViewGroup,配置属性

重写View来实现全新控件

继承View 并重写它的onDraw()、onMeasure()方法来实现绘制,重写onTouchEvent()处理点击事件

自定义ViewGroup

继承ViewGroup并添加子View,ViewGroup管理子View的测量 布局 绘制等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值