Android群英传笔记系列一view的介绍
学习完第一行代码后,继续学习Android群英传,希望能坚持下去,好好学习完这本书,并及时做好相关笔记,巩固相关知识;
一. View的介绍:
1`.我们先来看下view树结构:
2.树结构内容:
a.viewparent是整棵树的核心,它统一调度和分配所有的交互管理事件。
b.控件分为viewgroup和view两种控件,viewgroup作为父控件可以包含多个vie w控件。
c.我们知道在使用控件前都要通过findViewById的方法来实例化控件,那么在树结构中,实际上表现为通过树的深度优先遍历来查找到对应的元素。
3.UI界面构架图:
4.UI界面构架图内容:
a.实际上每个activity都包含一个window对象,而window对象是通过PhoneWindow来实现的。
b.PhoneWindow又将一个DecorView设置为整个应用窗口的根View。(简单的来说就是,我们所看到的整个手机屏幕内容就是整个的DecorView);
c.然后在我们手机应用中,一般含有两个view,一个是标题栏,即TitleView,另一个就是呈现内容的view,即ContentView.(当然,我们也可以通过一些办法隐藏,比如在setContentView()之前使用:
requestWindowFeature(Window.FEATURE_NO_TITLE)的方法即可。)
d.界面的显示过程:当程序在onCreate()方法中调用setContentView方法后,ActivityManagerService会回调onResume方法,系统便会将整个DecorView添加到PhoneWindow中。
二. View的测量:
1.测量的模式有三种:
EXACTLY模式:指的是精确值模式,比如我们设置layout_width=30dp,那么这种便属于精确值模式。
AT_MOST模式:指的是最大值模式,比如我们使用的wrap_content便是属于这种模式,允许随着内容的变化而变化,只要不超过父控件的所允许的最大尺寸即可。
UNSPECIFIED模式:这个是没有限制的模式,想要多大就可以多大,一般是在自定义view中使用。
2.关于重写onMeasure()方法:
a.为什么要重写onMeasure方法?
因为view类默认的onMeasure方法只支持EXACTLY模式,所以如果我们想要用指定wrap_content的大小的话,就必须要重写该方法。
b.重写onMeasure的过程:
(1)创建一个类继承至view:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); }
我们会看到这样的一个初始的onMeasure函数,然后我们来看下super.OnMeasure的方法:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec)); }
所以在这里我们要重写setMeasuredDimension这个函数:我们再下面添加这样一句话
setMeasuredDimension(measureSize(200,widthMeasureSpec),measureSize(200,heightMeasureSpec));
我们来看下这句话的含义,实际上我们自定义了一个measureSize的函数,然后分别传入两个参数,第一个为默认值,第二个实际值。然后我们来看下这个自定义函数是如何实现的:
private int measureSize(int defaultSize,int measureSpec){ int result=0;//定义result来作为返回值 int specMode=MeasureSpec.getMode(measureSpec);//获取到测量的模式 int specSize=MeasureSpec.getSize(measureSpec);//获取到测量值 if (specMode==MeasureSpec.EXACTLY){//如果为精确测量,返回测量值即可 result=specSize; }else{ result=defaultSize;//如果为其他两种模式,设置为默认值 if (specMode==MeasureSpec.AT_MOST){//如果为最大值模式,我们要获取到默认值和测量值中最小的值 result=Math.min(result,specSize); } } return result; }
最后我们在xml文件中引用这个自定义的view:
<main.view.com.view.viewTest android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ff0000" />