Android群英传第三章笔记·Android控件架构与自定义控件详解
2016-04-22 17:55
603 查看
Android控件架构
Android中,控件大致被分为两类,即ViewGroup控件与View控件。ViewGroup控件作为父控件可以包含多个View控件,并管理其包含的View控件。通常在Activity中使用的findViewById()方法,就是在控件树中以树的深度优先遍历来查找对应元素。
View树结构:
UI界面架构图:
PhoneWindow将一个DecorView设置为整个应用窗口的根View。
DecorView将要显示的具体内容呈现在了PhoneWindow上,这里面的所有View的监听事件,都通过WindowManagerService来进行接收,并通过Activity对象来回调相应的onClickLisener。
在代码中,程序在onCreate方法调用setContentView方法后,ActivityManagerService会回调onResume方法,此时系统才会把整个DecorView添加到PhoneWindow中,并让其显示出来,从而完成界面的绘制。
View的测量
Android在绘制View前,也必须对View进行测量,即告诉系统该画一个多大的View。这个过程在onMeasure方法中进行。Android给我们提供了一个设计短小精悍却功能强大的类——MeasureSpec类,通过它来帮助我们测量View。MeasureSpec是一个32位的int值,其中高2位为测量的模式,低30位为测量的大小,在计算中使用位运算的原因是为了提高并优化效率。
onMeasure方法:父控件传递给子控件的“建议”尺寸大小,两个参数表示宽高大小及测量模式(MeasureSpec类介绍及使用详解)。如果是ViewGroup,且大小为Wrap_content时,则需要遍历所有子View测量他们的大小,然后设置自身的大小。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}
setMeasureDimension方法:将测量后的尺寸传递给子控件,完成测量工作。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasureDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec));
}
public static int measureWidth(int measureSpec) {//根据父控件给的建议尺寸和测量模式,计算相应的尺寸 int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); switch (specMode) { case MeasureSpec.UNSPECIFIED: result = size; break; case MeasureSpec.AT_MOST: result = 200;//指定view的大小 result = Math.min(result, specSize); break; case MeasureSpec.EXACTLY: result = specSize; break; } return result; }
ViewGroup的子View位置设定
在ViewGrope及其子View完成测量之后,需要对子view进行放置位置的设定。在放置子view前,需要确定整个vewGroup的高度。然后在OnLayout方法中遍历调用子view的layout方法设定具体位置。View的绘制
过程:重写onDraw(),在Canvas对象上绘制图形。Canvas为系统2D绘图API必须要使用的对象。canvas通常会带有一个bitmap参数,用于存储绘制在canvas上的像素信息。当创建了含有bitmap的canvas对象后,所有canvas.drawxxx方法都发生在这个bitmap上。值得注意的是,view的onDraw方法中会创建两个bitmap,并将第二个bitmap封装到另一个canvas对象中,只在第二个bitmap上进行绘图。
ViewGroup的绘制:如果没有设置背景色,不会调用onDraw方法,而是调用dispatchDraw方法绘制子View。原理也是遍历子view并调用其绘制方法。
自定义View
自定义View通常需要重写onDraw方法来绘制自定义内容。如果设置了wrap_content属性,那么必须重写onMeasure方法测量大小。View中有一些重要的回调方法:
onFinishInflate():从XML加载组件后回调
onSizeChanged():组件大小改变时回调
onMeasure:测量
onLayout():回调该方法来确定显示的位置
onTouchEvent():监听到触摸事件回调
实现自定义控件的方式
对现有控件进行拓展
@Override
protected void onDraw(Canvas canvas) {
//父类绘制之前,实现自己的效果
super.onDraw(canvas);
//父类绘制完成后,再实现自己的效果
通过组合来实现新的控件
自定义属性
命名控件 介绍
重写View来实现全新的控件 例子:音频条形图
自定义view的一个例子
事件拦截机制
几个重要的方法:dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent.从ViewGroup到view的事件分发和处理回调事件顺序如下(以ViewGroupA,ViewGroupB,view为例):
ViewGroupA.dispatchTouchEvent –> ViewGroupA.onInterceptTouchEvent –> ViewGroupB.dispatchTouchEvent –> ViewGroupB.onInterceptTouchEvent –> view.dispatchTouchEvent –> view.onTouchEvent –> ViewGroupB.onTouchEvent –> ViewGroupA.onTouchEvent
解释:
dispatchTouchEvent方法用于分发事件,一般不用重写。onInterceptTouchEvent用来拦截TouchEvent,onTouchEvent用来处理TouchEvent。
onInterceptTouchEvent返回true则拦截事件,不往下分发;onTouchEvent返回true则不往上回调。
相关文章推荐
- Android群英传第一章笔记·Android体系与系统架构
- android mvp架构
- 为什么主流网站无法捕获 XSS 漏洞?
- 为什么主流网站无法捕获 XSS 漏洞?
- 为什么主流网站无法捕获 XSS 漏洞?
- WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例
- Web网站中利用JavaScript中ActiveXObject对象获取硬件信息(显示器数量、分辨率)从而进行单双屏跳转
- 查看网站上保存的密码
- CQRS架构简介
- 用Nikto探测一个网站所用到的技术
- BI的架构模型
- LANMT架构搭建jspxcms
- 技术架构学习笔记(八) 第三方支付架构原则(转)
- javascript在线调试分享网站
- 发布网站配置IIS(把网上找到的解决方法综合了一下)
- MMORPG服务器架构
- 微服务架构与可持续交付实践
- WEB系统架构
- .Net4.0的网站在IE10、IE11出现“__doPostBack未定义”的解决办法
- 浅谈web网站架构演变过程