Android 开发艺术探索 读书笔记4

第四章 View的工作原理

三大流程 测量流程(measure)、布局流程(layout)、绘制流程(draw)。

一,ViewRoot和DecorView

    ViewRoot对应于ViewRootImpl类,他是连接windowManager和DecorView的纽带。

    方法:performTraversals


measure 决定了View宽和高getMeasureWidth和getMeasureHeight,Layout决定了View四个顶点的坐标和实际View宽和高getTop、getBottom、getLeft、getRight

  DecorView作为顶级View是一个FrameLayout,一般情况下是一个LinearLayout有上下两个部分(titlebar 和android.R.id.content)

  我们的setContentView()就是在content中添加View。
得到content:
ViewGroup content=findViewById(R. android.id.content) .
得到我们设置的
View:conten.getChildAt(0)
二、理解MeasureSpec:
     在测量过程中,系统会将View的LayoutParams根据父容器所施加的规则转换成对应的MeasureSpec,然后根据measureSpec来测量View的宽和高。
1. MeasureSpec代表一个32位的int值,高2位SpecMode:测量模式;低30位SpecSize:某种测量模式下的规格大    小。P192
SpecMode的三个类:UNSPECIFIED: 父容器不对View有任何限制,这种情况一般用于系统内部,表示一种的量状态。EXACTLY:父容器已经检测出View所需要的精确大小,这个时候的View的最终大小就是SpecSize所指定的值。对应于LayoutParams中的match_parent和具体数值这两种模式。AT_MOST:父容器指定了一个可用大小SpecSize,View的大小不能大于这个值, 对应LayoutParams的wrap_content
2.MeasureSpec 和;LayoutParams的对应关系
  LayoutParams.MATCH_PARENT:精确模式,大小就是窗口大小
LayoutParams.WRAP_CONTENT:最大模式,大小不定,但是不能超过窗口大小。
固定大小:精确模式,大小为LayoutParams指定的大小


 对于普通的View,其MeasureSpec由父容器的MeasureSpec和自身的LayoutParams来决定,那么针对不同的父容器和View本身不同的LayoutParams,View就可以有多种MeasureSpec。当View采用固定宽和高时,不管父容器的MeasureSpec是什么,View的MeasureSpec都是精确模式并且遵循LayoutParams中的大小。当View的宽和高是match_parent时,如果父容器是精准模式,那么View也是精准模式,并且其大小是父容器的剩余空间;如果父容器是最大模式,那么View也是最大模式,并且其大小不会超过父容器的剩余空间。当View的宽和高是wrap_content时,不管父容器是精准模式还是最大模式,View的模式总是最大化并且不能超过父容器的剩余空间。UNAPECIFIED模式主要用于系统内部多次Measure的情形,一般不关注。

三、View的工作流程

1.measure过程

   由View的measure来完成 他是一个final的方法,子类不能重写。它会调用onMeasure方法p199

  结论:直接继承View的自定义控件需要重写onMeasure方法并设置wrap_content时的自身大小,否则在布局中使用wrap_content 就相当于使用match_parent,查表可得。

 ViewGroup的measure过程

  除了完成自己的measure过程还会去便利所有子元素的measure方法,各个子元素再去递归这个过程。ViewGroup是一个抽象类,它提供了一个measureChildren方法

2.Layout过程

layout的作用是ViewGroup用来确定子元素的位置,当位置确定后,他在onLayout中会遍历所有子元素并调用其layout方法,

3.draw过程

(1)绘制背景background.draw(canvas)

(2)绘制自己(onDraw)

(3)绘制children(dispatchDraw)

(4) 绘制装饰(onDrawScrollBars)

4.自定义View

1.继承View重写onDraw方法

2.继承ViewGroup派生特殊的Layout

   这种方法主要用于实现自定义布局,需要合适的处理ViewGroup的测量,布局这个过程p225

3.继承特定的View(比如TextView)

4.继承特定的ViewGroup(比如LinearLayout)

注意:

1.让View支持wrap_content

        2.如果有必要,让你的View支持padding

3,尽量不要在View中使用Handler,没必要。View内本身提供了Post系列方法。

4.View如果有线程或者动画,需要及时停止,参考View#onDetachedFromWindow

5.View带有滑动嵌套的情形时,需要处理好滑动冲突

5.添加自定义属性 系统自带属性都是以android开头的

(1)在values目录下面创建自定义属性XML,比如attrs.xml也可以选择类似于以attrs_开头的文件名,


除了color格式,还有reference资源id,dimension尺寸 String integer和boolean基本数据类型

(2)在View构造方法中解析自定义属性的值并做相应的处理。


首先加载自定义属性集合CircleView,接着解析CircleView属性集合中的circle_color属性,解析完自定义属性后,通过recycle方法实现资源。

(3).在布局文件中自定义属性

注意:为了使用自定义属性,必须在布局文件中加入schemas声明,xmlns:app=http://schemas.android.com/apk/res_auto在这个声明中,app是自定义属性的前缀,当然也可以换其他名字,但是CircleView中的自定义属性的前缀必须和这里的一致,然后就可以在CircleView中使用自定义属性了。比如app:circle_color="@color/light_green",还有一种schemas的命名方式就是在apk/res/后面附上应用的包名


2xm="













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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值