Andriod中Style/Theme原理以及Activity界面文件选取过程浅析
通过对前面的一篇博文<从setContentView()谈起>的学习,我们掌握了Activity组件布局文件地创建过程以及
其顶层控件DecorView,今天我们继续庖丁解牛---深入到其中的generateLayout()方法,步步为营掌握一下内容:
1、Activity中Theme(主题)的系统定义以及使用之处;
2、如何根据设置的Feature(属性)选择合适的布局文件。
另外,对于下文中Theme和Style的概念进行一个简要说明:
都是由 我们看看Android另外一个Theme.NoTitleBar属性定义,默认继承了"Theme"集合。
true
其实xml文件中声明的任何元素(包括属性),必须通过代码去获取他们的值,然后进行适当地逻辑运算。那么
系统是在什么地方去解析这些Window属性,并且选择合适地布局文件?
二、Theme主题的解析以及布局文件的选取
如果对setContentView()调用过程不太熟悉的朋友,可以先看看前面一篇博文<从setContentView()谈起>。
今天我们深入到其中generateLayout()方法,该方法地主要作用就是解析这些Window属性,然后选择合适地
布局文件作为我们地Activity或者Window界面地承载布局文件,即DecorView的直接子View。
在进行具体分析之前,Android还提供了另外两种简单API让我们制定界面的风格,如下两个方法:
1、requestFeature() 设定个该界面的风格Feature,例如,FEATURE_NO_TITLE(没有标题) 、
FEATURE_PROGRESS(标题栏带进度条)。必须在setContentView()前调用,否则会报异常。
FEATURE属性定义在Window.java类
2、getWindow().setFlags(),为当前的WindowManager.LayoutParams添加一些Flag。
Flag标记定义在WindowManager.LayoutParams.java类。
通过这两种方法隐藏状态栏和标题栏的例子为:
@Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); //hidetitlebarofapplication //mustbebeforesettingthelayout requestWindowFeature(Window.FEATURE_NO_TITLE); //hidestatusbarofAndroid //couldalsobedonelater getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.main); } 完整例子,可见于博文
源码分析:
这两个方法是在Window.java类实现的,如下:
publicclassWindow{ /**Flagforthe"optionspanel"feature.Thisisenabledbydefault.*/ publicstaticfinalintFEATURE_OPTIONS_PANEL=0; /**Flagforthe"notitle"feature,turningoffthetitleatthetop *ofthescreen.*/ publicstaticfinalintFEATURE_NO_TITLE=1; /**Flagfortheprogressindicatorfeature*/ publicstaticfinalintFEATURE_PROGRESS=2; /**Flagforhavinganiconontheleftsideofthetitlebar*/ publicstaticfinalintFEATURE_LEFT_ICON=3; /**Flagforhavinganiconontherightsideofthetitlebar*/ publicstaticfinalintFEATURE_RIGHT_ICON=4; /**Flagforindeterminateprogress*/ publicstaticfinalintFEATURE_INDETERMINATE_PROGRESS=5; /**Flagforthecontextmenu.Thisisenabledbydefault.*/ publicstaticfinalintFEATURE_CONTEXT_MENU=6;//菜单 /**Flagforcustomtitle.Youcannotcombinethisfeaturewithothertitlefeatures.*/ publicstaticfinalintFEATURE_CUSTOM_TITLE=7; //默认的FEATURESFEATURE_OPTIONS_PANEL&FEATURE_CONTEXT_MENU protectedstaticfinalintDEFAULT_FEATURES=(1<*created. *Thesewillbesetforyoubasedonthe{@linkandroid.R.attr#windowIsFloating} *attribute. *@paramflagsThenewwindowflags(seeWindowManager.LayoutParams). *@parammaskWhichofthewindowflagbitstomodify. */ //mask代表对应为的掩码,设置对应位时,需要先清空对应位的掩码,然后在进行或操作。类似的函数可以见于View.java类的setFlags()方法 publicvoidsetFlags(intflags,intmask){ finalWindowManager.LayoutParamsattrs=getAttributes();//当前的WindowManager.LayoutParams属性 //将设置的flags添加至attrs属性中 attrs.flags=(attrs.flags&~mask)|(flags&mask); mForcedWindowFlags|=mask; if(mCallback!=null){//Activity和Dia