【View工作原理】ViewRoot、DecorView、MeasureSpec和LayoutParams
2016-06-07 19:31
609 查看
一、窗口层级关系
1、PhoneWindow
是Android中最基本的窗口系统,每个Activity会创建并持有一个PhoneWindow对象,是Activity和整个View系统交互的接口。2、DecorView
1、Dispatch ViewRoot分发来的key、touch、trackball等外部事件。2、DecorView有一个直接的子View,我们称之为System Layout,这个View是从系统的Layout.xml中解析出的,它包含当前UI的风格,如是否带title、是否带process bar等。
3、作为PhoneWindow与ViewRoot之间的桥梁,ViewRoot通过DecorView设置窗口属性。
3、System Layout
目前android根据用户需求预设了几种UI 风格,通过PhoneWindow通过解析预置的layout.xml来获得包含有不同Window decorations的layout,我们称之为System Layout,我们将这个System Layout添加到DecorView中。预设风格可以通过PhoneWindow方法requestFeature()来设置,需要注意的是这个方法需要在setContentView()方法调用之前调用。
4、Content Parent
Content Parent这个ViewGroup对象才是真真正正的ContentView的parent,我们的ContentView终于找到了寄主,它其实对应的是System Layout中的id为“content”的一个FrameLayout。这个FrameLayout对象包括的才是我们的Activity的layout。5、Activity Layout
ActivityLayout就是我们通过SetContentView设置的Layout,是真正和用户交互的部分。二、ViewRoot
ViewRoot是GUI管理系统与GUI呈现系统之间的桥梁,根据ViewRoot的定义,我们发现它并不是一个View类型,而是一个Handler。它的主要作用如下:
1、向DecorView分发收到的用户发起的event事件,如按键,触屏,轨迹球等事件;
2、与WindowManagerService交互,完成整个Activity的GUI的绘制。View的三个流程都是通过ViewRoot来完成的。
三、MeasureSpec
一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。一个MeasureSpec由大小和模式组成。它有三种模式:UNSPECIFIED(未指定),父元素部队自元素施加任何束缚,子元素可以得到任意想要的大小;EXACTLY(完全),父元素决定自元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小;AT_MOST(至多),子元素至多达到指定大小的值。它常用的三个函数:
1、static int getMode(int measureSpec):根据提供的测量值(格式)提取模式(上述三个模式之一)
2、static int getSize(int measureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)
3、static int makeMeasureSpec(int size,int mode):根据提供的大小值和模式创建一个测量值(格式)
四、LayoutParams
LayoutParams封装的是View向父容器传达自己意愿的信息,它封装了Layout的位置、高、宽等信息,表达自己想变成一个什么尺寸的View。使用示例:
SwipeRefreshLayout refreshLayout = new NsRefreshLayout(this); refreshLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); ScrollView scrollView = new ScrollView(this); TextView textView = new TextView(this); textView.setText("TextView"); scrollView.addView(textView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); refreshLayout.addView(scrollView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
相关文章推荐
- 配置View桌面时找不到域的解决方法
- 完全克隆的虚拟桌面部署问题
- 实例讲解JavaScript的Backbone.js框架中的View视图
- Android中View自定义组合控件的基本编写方法
- Android 自定义View步骤
- Android自定义View仿QQ健康界面
- Android重写View实现全新的控件
- Android自定义View过程解析
- Android 自定义View 密码框实例代码
- Android自定义View软键盘实现搜索
- thinkphp3.x自定义Action、Model及View的简单实现方法
- codeigniter中view通过循环显示数组数据的方法
- MVVM模式中ViewModel和View、Model有什么区别?
- Android使用WindowManager构造悬浮view
- Android App开发中自定义View和ViewGroup的实例教程
- Android自定义View实现左右滑动选择出生年份
- Android应用开发中View绘制的一些优化点解析
- 自定义滑动按钮为例图文剖析Android自定义View绘制
- Android自定义View实现带数字的进度条实例代码
- Android重写View并自定义属性实例分析