布局阶段

这一阶段是对于布局的设置,因为对于一般的软件而言,当你点击进去某个activity时,往往这个activity与之前的activity有一些地方的显示
是相同的,比如,头部和尾部,那么这时为了减少工作量,我们可以使用include标签,对于include标签的使用,在这里提一下需要注意的地方,
如果你要在include标签中重新指定布局参数(android:layout_*属性),,就必须覆盖android:layout_height和android:layout_width。因为这
样才会生效,不然会提示错误。如果你是想指定过一个id,那么重新指定的id会覆盖原来的id。同时这里需要提一下很重要的一点,如果你想在
代码中为include标签重新指定内容,那么如果你直接通过id找到这个include标签,然后将view添加到这个标签中,这样是得不到的,可能就是
你通过id的确找到了这个标签,但是这个并不是真正的viewgroup,所以你无法将自己的view添加到上面,代码如下:

public void setActivityTitle(int RLayoutId,int account){  
//找到include标签  
 LinearLayout linearLayout1= (LinearLayout) findViewById(R.id.include1);  
//找到要附在include标签上的view  
 LinearLayout linearLayout= (LinearLayout) LayoutInflater.from(this).inflate(RLayoutId, null);  
 TextView textView= (TextView) linearLayout.findViewById(R.id.usertitlt_tv);  
 textView.setText(getString(R.string.useractivitytitle_name) + "(" + account + ")");  
//附在include标签上  
 linearLayout1.addView(linearLayout);  
 }  

这样是得不到的,那么我们应该怎么做呢?代码如下:

 public void setActivityTitle(int RLayoutId,int account){  
 //找到include标签  
    LinearLayout linearLayout1= (LinearLayout) findViewById(R.id.include1);  
  //将这个标签设置为不可见,注意这里设置为不可见,而不是GONE,因为如果是GONE就意味着这个include标签不存在,那么可能会影响整个布局  
    linearLayout1.setVisibility(View.INVISIBLE);  
//找到这个include标签在的那个整个布局,之所以这里通过id来找,而不是通过inflate来生成,是因为生成之后你还需要再setcontextview()。  
    RelativeLayout relativeLayout= (RelativeLayout) findViewById(R.id.mainRelativeLayout);  
    LinearLayout linearLayout= (LinearLayout) LayoutInflater.from(this).inflate(RLayoutId, null);  
    TextView textView= (TextView) linearLayout.findViewById(R.id.usertitlt_tv);  
    textView.setText(getString(R.string.useractivitytitle_name) + "(" + account + ")");    
 //将要附加的view附加在整个布局上。    
    relativeLayout.addView(linearLayout);    
}

这就是使用include标签需要注意的一些地方。
在这里也需要说一下布局的各个属性问题,由于篇幅问题,这里就提一个,就是layout_marginpadding的区别,layout_margin是控件在布局显
示的样子,padding则是控件的内容在控件中的位置,同时,Layout_grivatygrivaty这两者与之相似,layout_grivatylayout_margin对应,
grivatypadding对应,那么,layout_margn与layout_grivaty有什么区别呢?grivaty与padding又有什么区别呢?layout_grivaty与grivaty
的值都是给定的,我们只能在这些给定的属性中选择,而layout_margn与padding的值我们可以任意给,相对于layout_grivaty和grivaty更灵活,
我们根据需要选择合适的属性。
总之有layout的就是跟控件在布局中显示有关,没有的则是控制控件的内容的位置。

今天在设置布局时,因为我们想将所有的title去掉,那么如果我们去每一个activity中找,并且去掉,这样是非常不合理的,因此我们需要在
一个activity中管理一下,因此我定义了一个activityFrame继承了activity,这样我真正的activity都可以继承自定义的activity,这样管理
起来就很方便,那么我们可以requestWindowFeature(Window.FEATURE_NO_TITLE);来让它没有标题,同时因为我们需要动态的添加布局,我们可以这么办,步骤可以分为三步:
1.先找到我们需要插入的位置的布局,如我要插入到下面布局中的relativeLayout布局中

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.jdk.myaa.MainActivity">
<include layout="@layout/title_layout" android:id="@+id/include1"></include>
<include layout="@layout/buttom_layout" android:id="@+id/include2"></include>
<RelativeLayout
android:id="@+id/main_bodyRelativeLayout"
android:layout_below="@id/include1"
android:layout_above="@id/include2"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
</RelativeLayout>

我们如何找到这个布局呢?通过代码: RelativeLayout relativeLayout= (RelativeLayout) findViewById(R.id.main_bodyRelativeLayout);
这样就找到了这个布局。
2.找到我们需要插入的布局,如我要插入如下布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
>
<GridView
    android:id="@+id/gv"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"
    android:paddingTop="130dp"
    android:horizontalSpacing="10dp"
    android:verticalSpacing="100dp"
    android:numColumns="3"
    android:layout_width="wrap_content"
    android:layout_height="200dp"
    android:listSelector="@drawable/myselector"
    ></GridView>
</LinearLayout>

这个如何寻找呢?通过下面代码:
ViewGroup v= (ViewGroup) LayoutInflater.from(this).inflate(R.layout.main_bodylayout, null);其中R.layout.main_bodylayout是上面
布局的名字。
3.将这个布局添加到对应的位置的布局中:
relativeLayout.addView(v);
这样就完成了动态添加,当然所添加的布局的属性会与你需要插入的布局属性相同,也就是跟第二步骤的布局相同,但是你也可以自己设置,设置的代码如下:

RelativeLayout.LayoutParams layoutParams=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT);
relativeLayout.addView(v,layoutParams);

这样就行了。 上面是添加一个布局到对应位置中去,那么如何添加一个控件到对应的位置中去呢?
这个步骤与上述类似
1.与上面一致
2.找到我们需要插入的控件,比如我想插入这个布局中的GridView控件,如下:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
>
<GridView
    android:id="@+id/gv"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"
    android:paddingTop="130dp"
    android:horizontalSpacing="10dp"
    android:verticalSpacing="100dp"
    android:numColumns="3"
    android:layout_width="wrap_content"
    android:layout_height="200dp"
    android:listSelector="@drawable/myselector"
    ></GridView>
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="hahaha"/>
</LinearLayout>

那么我们该如何找到呢?代码如下:

ViewGroup v= (ViewGroup) LayoutInflater.from(this).inflate(LayoutId, null);
GridView g= (GridView) v.findViewById(R.id.gv);
v.removeView(g);

这里说一下第三行代码的作用,如果你没有这行代码,那么就会报错:
The specified child already has a parent. You must call removeView() on the child's parent first.
也就是说这个控件已经有一个parent了,我们要使用这个控件,就必须使用这个parent,如果你要强制使用这个
控件,那么你就需要让这个控件与这个parent脱离父子关系,也就是用这行代码,要理解这个,我们先理一下
activitywindowview的关系其实我们可以这么理解,假设activity是一个工人,他做了一个window,而这个
window需要玻璃,玻璃就是这个view,更准确是viewgroup,也就是根视图,然后我们需要打扮这个窗户,也就是
往窗户上贴窗花,假设我们的窗花是需要贴在纸上,然后让纸贴在玻璃上,因为这样我们以后要清除的时候,只要
把纸撕了就行,也就是说方便管理,然后这个窗花就是控件,纸就是view,也就是各种子视图,然后我们这里的情
况是要在这张纸上贴别的纸上的窗花,我们当然得把它撕下来先,也就是去掉父子关系,这就是第三行代码的作用
。不知道这么说你们是不是理解了呢?这里再加一些内容,其中的窗户实际上是phonewindow,而玻璃是viewgroup,
那么这个玻璃是怎么创建的呢?是通过activity方法中的attach()方法创建的,通过源代码你也可以看的到这是一个
phonewindow对象,那么什么时候调用的attach()方法呢?是在ActivityThreadperformLaunchActivity中调用了,
那么这里的纸是怎么创建的呢?是通过LayoutInflaterinflate()方法创建的,原料就是那些layout布局文件,而
这里的窗花就是控件,这个是在layout中写出来的或者用代码动态生成。将窗花贴在纸上是通过addview()方法,将
纸贴在玻璃上,是通过setcontentview()方法。那么玻璃(viewgroup)怎么生成的呢?实际上是通过installDecor();
方法得到的,这里的viewgroup更准确的说是DecorView,而installDecor();方法是生成DecorView,并且根据窗口属
性加载顶级视图布局、获取mContentParent、设置一些基本属性等。接下来还是放一张图片来说一下:

1

一、DecorView为整个Window界面的最顶层View。
二、DecorView只有一个子元素为LinearLayout。代表整个Window界面,包含通知栏,标题栏,内容显示栏三块区域。
三、LinearLayout里有两个FrameLayout子元素。
(20)为标题栏显示界面。只有一个TextView显示应用的名称。也可以自定义标题栏,载入后的自定义标题栏View将加入FrameLayout中。
(21)为内容栏显示界面。就是setContentView()方法载入的布局界面,加入其中。
这样是不是清晰点了。
3.与上面一样。
relativeLayout.addView(g);至于这里为什么事g而不是v应该理解吧。

这里还需要说一下,setcontentview()方法的作用,作用其实就是将纸贴在玻璃上,但是这里需要提一下:
activity 调用 setContentView() 时,Android 才会去绘制 layout 上的各个元素,并为其分配内存。
只有分配了内存以后,才能继续执行findViewById(); 才能得到引用,不然得到空引用。空引用意味着,
后面使用相应变量时就会发生访问的对象不存在的问题。当Activity重新setContentView()以后,那些之前
绘制的控件,内存都被灭掉了。这也就是说,你需要先setcontentview,然后再将布局动态添加上去。不然
就白费了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容