Android View架构总结
View和Activity的区别
View有哪些?
Android中控件大致被分为两类ViewGroup,View。ViewGroup作为容器管理View。Android视图,是类似于Dom树的架构。父视图负责测量定位绘制等操作。我们经常在用的findViewById方法代价昂贵的原因,就是因为他负责至上而下遍历整棵控件树,来寻找View实例,在重复操作中尽量少用。现在在用的很多控件都是直接或者间接继承自View的,如下图。
ViewGroup是什么?
一个ViewGroup是一个可以包含子View的容器,是布局文件和View容器的基类。在这个类里定义了ViewGroup.LayoutParams类,这个类是布局参数的子类。 其实ViewGroup也就是View的容器。通过ViewGroup.LayoutParams来指定子View的参数。ViewGroup作为一个容器,为了制定这个容器应有的标准所以为其指定了接口。
ViewGroup继承自View,并实现了两个接口ViewParent和ViewManager。 ViewManager提供了三个抽象方法addView,removeView,updateViewLayout。用来添加、删除、更新布局。 ViewParent主要提供了一系列操作子View的方法例如焦点的切换,显示区域的控制等等。
View的层级结构是什么?
为什么Google产生ViewGroup?
实际上所有的事情View都能做,包括显示复杂的界面,我们只需要设计一个复杂的View即可。例如短信通知的icon,一个可以显示图片又可以显示文字的View,我们后期学习了View的draw方法后,可以轻松的设计一个View来达到这个效果,但是这样不仅复杂,而且重用性较差,还会因为一点小改动而重复的创造轮子,这显然不符合程序员偷懒的原则,所以我们可以完全把ImageView和TextView组合到一起就可以了,这个时候我们就需要一个容器,ViewGroup,来装这两个View。 ViewGroup和View最大的不同是可以组合多个View,那么多个View在一起,该如何摆放,这就是ViewGroup需要解决的问题。View的层级结构是什么?
我们看到的界面,都是以一个ViewGroup作为根View,通过往ViewGroup中添加子View(可以是View,也可以是ViewGroup),来组合出各具特色的界面。 这种从根到叶的组合方式,我们可以看做成一个View树。(类似于XML),而View的显示和事件处理,都是依赖于这个View树。 绘制和事件处理的起始点,都是从根View开始一级一级的往下传递。我们从任意一层发起绘制,都将反馈到根View,然后再从上往下传递。 之前我们说过根View就是Window中的DecorView,也就是一个FrameLayout。
View的onMeasure()/onLayout()/onDraw()方法做了什么?
Android是如何绘制View的
当一个Activity启动时,会被要求绘制出它的布局。Android框架会处理这个请求,当然前提是Activity提供了合理的布局。绘制从根视图开始,从上至下遍历整棵视图树,每一个ViewGroup负责让自己的子View被绘制,每一个View负责绘制自己,通过draw()方法.绘制过程分三步走。这个也是我们老生常谈的onMeasure(),
onLayout();
onDrawn();
整个绘制流程是在ViewRoot中的performTraversals()方法展开的。
private void performTraversals() { ...... //最外层的根视图的widthMeasureSpec和heightMeasureSpec由来 //lp.width和lp.height在创建ViewGroup实例时等于MATCH_PARENT int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width); int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height); ...... mView.measure(childWidthMeasureSpec, childHeightMeasureSpec); ...... mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight()); ...... mView.draw(canvas); ...... }
Android中Invalidate和postInvalidate和requestLayout的区别
invalidate:View本身调用迫使view重画。是在UI线程自身使用。
postInvalidate:是在非UI线程使用。
Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。
Android程序中可以使用的界面刷新方法有两种,分别是利用Handler和利用postInvalidate()来实现在线程中刷新界面。
为什么调用requestWindowFeature()方法一定要在setContentView()方法调用之前?
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Android官方开发文档Training系列课程中文版:Android的JNI相关
原文地址:http://android.xsoftlab.net/training/articles/perf-jni.html JNI的全称为Java Native Interface,中文意思是Java本地接口。它定义了Java代码与C/C++代码之间的交互方式。它是两者的桥梁,支持从动态共享库中加载代码。虽然有些复杂,但是它的执行效率还是蛮高的。 如果你对JNI还不太熟悉,那么可以通过Java Native Interface Specification来了解一下JNI的大致工作流程以及JNI的特性。 JavaVM与JNIEnv JNI定义了两个关键的数据结构:”JavaVM”与”JNIEnv”。这两个函数本质上都为指向函数指针的指针表。JavaVM提供了”接口调用”功能,该功能允许创建、销毁JavaVM。理论上每个进程可以拥有多个虚拟机,但是在Android中只允许出现一个。 JNIEnv提供了大部分的JNI功能。任何本地方法都以JNIEnv为第一回调参数。 JNIEnv用于线程局部存储。正出于这个原因,所以不能在线程间共享JNIEnv。如果不能够通过其它方式获取其对应的JNI...
- 下一篇
Android源码浅析(六)——SecureCRT远程连接Linux,配置端点和字节码
Android源码浅析(六)——SecureCRT远程连接Linux,配置端点和字节码 需要编译源码的同学,一般都是win+虚拟机吧,但是再虚拟机里体验并不是很好,所有市面上有很多的软件能够做到在win端直接调用linux的终端,比如今天说的SecureCRT或者XShell等软件,我们先来看下SecureCRT的一些简单的介绍: “SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的理想工具。通过使用内含的VCP命令行程序可以进行加密文件的传输。有流行CRTTelnet客户机的所有特点,包括:自动注册、对不同主机保持不同的特性、打印功能、颜色设置、可变屏幕尺寸、用户定义的键位图和优良的VT100,VT102,VT220和ANSI竞争.能从命令行中运行或从浏览器中运行.其它特点包括文本手稿、易于使用的工具条、用户的键位图编辑器、可定制的ANSI颜色等.SecureCRT的SSH协议支持DES,3DES和RC4密码和密码与RSA鉴别.” 似乎是很强大,那我们来安装一下,在网上随处可下载,下载成功后打开SecureCRT,他开始是空空如也的,你需要左上角 1.New ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- MySQL8.0.19开启GTID主从同步CentOS8
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS7设置SWAP分区,小内存服务器的救世主