layoutopt工具提示可以将<FrameLayout/>换成<merge/>。其实<merge/>标签在UI的结构优化中起着非常重要的作用,通过它可以删减多余的层级,达到优化UI的目的。
  再来看一下上篇博客中使用的框架布局的树形结构图:再来看一下上篇博客中使用的框架布局的树形结构图: 2 x' w) \' A! T0 y1 e2 j2 q

根节点和LinearLayout上面那个子树为android的窗口布局,后面的TextView即为标签。黄色框内的这部分树形图即为我们的布局。可以发现红色框出的FrameLayout是另一个FrameLayout的唯一子元素,并且该父节点并没有额外的属性,也就是说,它是完全冗余的,这时候就要用<merge/>标签来解决这个问题。用<merge/>替换原来的<FrameLayout/>标签,修改后的布局代码如下:
<?xml version="1.0" encoding="utf-8"<merge xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><TextViewandroid:layout_width="300dip"android:layout_height="300dip"android:background="#00008B"android:layout_gravity="center"/>/ <TextView android:layout_width="250dip"android:layout_height="250dip"android:background="#0000CD"android:layout_gravity="center"/><TextViewandroid:layout_width="200dip"android:layout_height="200dip"android:background="#0000FF"android:layout_gravity="center"/><TextViewandroid:layout_width="150dip"android:layout_height="150dip"android:background="#00BFFF"android:layout_gravity="center"/><TextViewandroid:layout_width="100dip"android:layout_height="100dip"android:background="#00CED1"android:layout_gravity="center"/></merge>5

6 {, [7 P' |1 U+ d
再观察下它的树形图,如图所示,显然层次更简单了。 4 K5 A4 p6 F( D3 U* hD' m

为什么会这样呢,因为Activity的根节点都是FrameLayout,所以用merge标签可以直接添加到这个FrameLayout而不要再增加一个FrameLayout节点。但是如果你的布局是以LinearLayout等为根节点,就不能这么做了。 / f' y0 r2 g$ a
<merge/>其实还有很多作用,它和<include/>标签就能完美的结合。<include/>标签用来实现代码的重用以及布局的模块化。如果UI中需要多次用到同一个布局, <include/>标签会大大提高我们的开发效率。看个例子:
新建一个共享布局:share.xml ; a- G% r( _E# l
<? xml version="1.0" encoding="utf-8" ?> * b" l; \+ O" x+ s" z
< LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" / J2 \( J: L7 }! z5 }5 M
android:orientation
="vertical" / C9 Z4 i+ w( X, j' p0 }
android:layout_width
="fill_parent" / M6 C( M8 A9 f, F; I- c) q
android:layout_height
="fill_parent"
>
< TextView1 i: y/ |4 _( e: [
android:layout_width ="fill_parent" 3 n( @" M: L* e: ]% }& y+ w
android:layout_height
="wrap_content" android:text ="这是一个共享布局" 8 ]# C7 d5 }! F: D/ z+ T3 z4 S( b
/>
</ LinearLayout >

然后在需要使用这个布局的布局中使用<include/>标签,并且我们可以重写它的一些属性(下面的代码就重写了它的id):
<? xml version="1.0" encoding="utf-8" ?>
< LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" % x/ q5 d4 g. w- x: [- e$ ^
android:orientation
="vertical" : N9 d% B& z" R" T8 E! V
android:layout_width
="fill_parent" 7 L/ _4 k0 o4 f/ G+ o
android:layout_height
="fill_parent" >
< include android:id ="@+id/new" layout ="@layout/share" ></ include > " e9 U; {6 y2 ?( n1 K- U6 c
</ LinearLayout >
1 r- r; _i5 Q- H, U( ^% B' v& A0 F
如果在我们的布局中只需要使用共享布局的内容,这时候就可以用merge标签,这样使得布局更加高效灵活。 1 h7 m9 {, w' k) x# u
<? xml version="1.0" encoding="utf-8" ?>
< merge xmlns:android ="http://schemas.android.com/apk/res/android" # M8 g+ U7 j" C) W9 N6 `
<include android:id
="@+id/newone" layout ="@layout/share" ></ include >
< include android:id ="@+id/newtwo" layout ="@layout/share" ></ include > 7 E- B# X- h; {( t' ~2 K/ K
</ merge > 0 D6 M( D" e8 u- e4 r4 N
3 z9 J$ _& J3 s( v0 f1 s
有了<include/>标签,很容易就能做到共享和重用布局,可是很多情况下,一个布局中有很多View并不常用,这就造成了资源的浪费,android为此提供了ViewStub标签来解决这个问题。在默认情况下ViewStub下的标签都有visibility=GONE属性(不可见),更重要的是在这个标签下的内容不会占用任何的空间。其实ViewStub和include类似,不过区别就在于ViewStub只会在你需要的时候进入你的界面,viewStub通过inflate()方法来通知系统加载其内部的View。这样就可以让我们既享受到<include/>的便利,又不会产生过多没用的View。 还是看个例子: + n' j; q% y( o) {& R
其中share.xml前面已经介绍过了,main.xml的布局文件: 7 M( y; a; U, N
<? xml version="1.0" encoding="utf-8" ?> t; d5 O* p3 ^1 u0 JR

< LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" ; ghz$ ]- J1 |& A
android:orientation ="vertical"
android:layout_width ="fill_parent"
android:layout_height ="fill_parent" / v/ }1 \" T, p; s3 C: a- F7 `
! H' y( R$ b9 `* s9 F; U' l
> % s6 C0 a' {# U- [! K- j+ b 2 a$ G# i. A# |- d
< Button4 I3 @: C& e: N9 q/ M, k6 _% W& A
: s2 A4 N8 u% m2 q) K& _8 {
android:id ="@+id/show"
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:text ="点击导入" ! {+ o8 F" f. b# m7 i5 A5 V8 B* X
/> $ L" n0 G, s5 z% D( z, y8 {u
: a/ \) M0 U! J$ |
< ViewStub
" Q3 c, o(N7 ?% NM" D
android:id ="@+id/viewStub" - F& M1 D( e% f( h& e
android:layout ="@layout/share" ( T) b, T8 U- V& J8 i' ], H
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
r1 M( v4 F3 t5 w% e
/> ( u* e' e2 Z: O7 N@1 r
r. |, z% U9 ]&
</ LinearLayout >
MyViewStub.java代码:
package com.notice520.viewstub;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.ViewStub;import android.view.View.OnClickListener;import android.widget.Button;public class MyViewStub extends Activity {private ViewStub mViewStub;private Button showButton;/**Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);//实例化ViewStub控件,这里可以看出我们必//须为ViewStub设定idmViewStub =(ViewStub)findViewById(R.id.viewStub);showButton =(Button)findViewById(R.id.show);/*为按钮添加点击监听事件,后面的章节会介绍*/showButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(mViewStub != null) {mViewStub.inflate();//点击即导入ViewStub标签的内容}}});}}


  运行效果如图所示,当点击按钮后,导入的布局就会显示,如图所示。这里要注意的是,其实很多时候我们不需要保留ViewStub的引用(这个例子中我们在字段里保留了ViewStub的引用),因为当ViewStub inflate后,这个ViewStub就从View层次中移除了。在读者深入学习后,会经常用到infate()方法来导入布局加载到原来的view上,那时候你会发现用ViewStub是个比那更好的办法。但是要注意的是,ViewStub还不支持<merge/>标签。

来自http://www.eoeandroid.com/thread-72281-1-1.html

更多相关文章

  1. tag tab label在android的区别
  2. Android(安卓)layout之优化:使用include和merge 标签
  3. Android(安卓)时间轴的实现
  4. Android(安卓)项目实战:智慧北京(黑马)
  5. Android(安卓)纯代码化编码1_关于布局
  6. 【笔记】颜色渐变标签之坑爹的 @android:color/transparent
  7. [送给不懂android的开发者]react-native如何替换android图标资源
  8. Android(安卓)键盘开发心得
  9. Android中使用DrawerLayout的注意点

随机推荐

  1. android对话框(非速成)
  2. Android中的服务(service)详解(三)--远程服务
  3. Android静态变量的生命周期
  4. 我对Android的理解
  5. ART深度探索开篇:从Method Hook谈起
  6. 万树IT:你的Android不好用的原因就是这些!
  7. android 新浪微博客户端的表情功能的实现
  8. ArcGIS Android(安卓)MapView离线浏览无
  9. Android(安卓)Training - 支持不同的设备
  10. Android(安卓)模仿QQ抢红包 listView实现