Android群英传笔记-View

View知识点

ui架构

每个Activity都包含一个window对象-phoneWindow。phoneWindow将一个DecorView作为应用窗口的根View。DecorView作为窗口的顶层视图,封装了一些窗口操作的通用方法,将要显示的具体内容呈现在PhoneWindow上,所有View的监听事件,通过WindowMangerService接收,通过Activity对象来回调相应的Listerner。DecorView将屏幕分为两部分(LinearLayout作为viewGroup),titileViewContentView.ContentView是一个id为content的FrameLayout,我们的xml文件就是放到这样一个FtameLayout里的。

用户可以通过requestWinowFeature()方法来设置全屏显示,这样就只有ContentView了,所以该方法只能在setContentView()方法之前执行。

当ActivityMangerService回调onResume()方法,系统才把整个decorView放到phoneWindow中,显示出来。

View的测量

view的测量在onMeasure()方法中进行。
MeasureSpec类----32为的int值,高两位是测量模式,低30位是测量的大小。使用位运算是为了提高和优化效率。

三种测量模式

EXACTLY: 精确值模式,为view指定大小,或者match_parent时使用

AT_MOST:最大值模式,一般被指定为wrap——content时使用,随着子控件的大小而改变。

UNSPECIFIED:不指定大小,一般在绘制自定义View时使用

view默认onMeasure方法只支持EXACTLY模式,如果自定义view想要支持wrap_content,那得重写onMeasure方法,指定wrap_content时的大小。

系统最终调用 setMeasureDimension(int measuredWidth,int measuredHeight)方法,其中两个int值是通过解析MeasureSpec对象得来的。注意,wrap_content时,采取的是默认值和测量值,较小的一个值

viewGoup的测量,当viewGroup为wrap_content时,会对子view进行遍历,最终决定自己的大小。其他模式时,通过指定值来确定自身大小。

View的绘制

调用**onDraw()**方法进行绘制。
onDraw()方法有一个Canvas canvas对象作为参数,可以使用这个对象进行直接绘图。

在其他地方使用canvas时,一般会传入一个bitmap对象
Canvas canvas=new Canvas(bitmap).
这个bitmap可以装载到其他画布之中,canvas的操作也是通过改变bitmap,使得view得以重绘。

viewgroup一般不会进行绘制,除非指定背景颜色之类。会调用dispatchDraw()方法,绘制子view。通过遍历

自定义View

自定义view有三种方式,扩展现有控件,组合控件,重写view实现全新控件

扩展现有控件

一般通过重写ondraw方法,结合一些其他方法的特性,来实现自定义的效果。
例如结合paint的渲染器,以及textView的onSizeChange
方法等等。具体可看书中介绍

组合控件

定义属性,在资源目录value中,创建attrs.xml,写明需要的自定义属性。
注意,代码中,获取完所有属性后,需要调用TypeArray的recyle方法进行资源回收。

组合控件,可以直接在代码中new Button这样来创建,也可以写在xml文件里,代码里再调用,第二种方法更方便一点。

处理事件:需要定义接口,并暴露给调用者。

在使用自定义view控件时,需要完整的包名。
例如 xmls:custom="…//res-auto"

重写view的全新控件

继承view类,重写onMeasure,onDraw等控制view的视图,重写onTouchEvent实现交互。也可以引入自定义属性。
具体内容看书。

事件拦截机制

以motionEvent举例,有dispatchToucnEvent()分发方法,onInterceptTouchEvent()拦截方法,以及onTouchEvent()处理方法。
那么从 Activity,到父view,子view的处理流程是怎样的?
分发:Activity->父view->子view
处理:子view->父view->Activity

事件分发时,可以重写onInterceptTouchEvent()进行拦截。
事件处理时,onTouchEvent()方法返回true,表示事件被处理了。返回false,表示不处理,传给父view处理。

明确知道事件的分发和处理流程十分重要,在实际项目中,就曾遇到keyEvent先被输入框先处理,导致activity处理时,输入框里有错误数据的情况。解决方法就是输入框 重写处理方法,返回false,表示不处理(场景支持我们的输入框不处理keyEvent事件)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值