上一篇博客中介绍了布局优化的工具,层级观察器Hierarchy Viewer和布局优化分析工具layoutopt。如果看过上篇博客的会注意到,layoutopt工具提示可以将换成。其实标签在UI的结构优化中起着非常重要的作用,通过它可以删减多余的层级,达到优化UI的目的。

再来看一下上篇博客中使用的框架布局的树形结构图:

android UI进阶之布局的优化(二)_第1张图片

根节点和LinearLayout上面那个子树为android的窗口布局,后面的TextView即为标签。×××框内的这部分树形图即为我们的布局。可以发现红色框出的FrameLayout是另一个FrameLayout的唯一子元素,并且该父节点并没有额外的属性,也就是说,它是完全冗余的,这时候就要用标签来解决这个问题。用替换原来的标签,修改后的布局代码如下:

            
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <merge xmlns:android="http://schemas.android.com/apk/res/android" 
  3. android:orientation="vertical" 
  4. android:layout_width="fill_parent" 
  5. android:layout_height="fill_parent" 
  6. > 
  7. <TextView 
  8. android:layout_width="300dip" 
  9. android:layout_height="300dip" 
  10. android:background="#00008B" 
  11. android:layout_gravity="center" 
  12. /> 
  13. <TextView 
  14. android:layout_width="250dip" 
  15. android:layout_height="250dip" 
  16. android:background="#0000CD" 
  17. android:layout_gravity="center" 
  18. /> 
  19. <TextView 
  20. android:layout_width="200dip" 
  21. android:layout_height="200dip" 
  22. android:background="#0000FF" 
  23. android:layout_gravity="center" 
  24. /> 
  25. <TextView 
  26. android:layout_width="150dip" 
  27. android:layout_height="150dip" 
  28. android:background="#00BFFF" 
  29. android:layout_gravity="center" 
  30. /> 
  31. <TextView 
  32. android:layout_width="100dip" 
  33. android:layout_height="100dip" 
  34. android:background="#00CED1" 
  35. android:layout_gravity="center" 
  36. /> 
  37. merge>  

再观察下它的树形图,如图所示,显然层次更简单了。

android UI进阶之布局的优化(二)_第2张图片

为什么会这样呢,因为Activity的根节点都是FrameLayout,所以用merge标签可以直接添加到这个FrameLayout而不要再增加一个FrameLayout节点。但是如果你的布局是以LinearLayout等为根节点,就不能这么做了。

其实还有很多作用,它和标签就能完美的结合。标签用来实现代码的重用以及布局的模块化。如果UI中需要多次用到同一个布局, 标签会大大提高我们的开发效率。看个例子:

新建一个共享布局:share.xml

            
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3. android:orientation="vertical" 
  4. android:layout_width="fill_parent" 
  5. android:layout_height="fill_parent" 
  6. > 
  7. <TextView 
  8. android:layout_width="fill_parent" 
  9. android:layout_height="wrap_content" 
  10. android:text="这是一个共享布局" 
  11. /> 
  12. LinearLayout> 

然后在需要使用这个布局的布局中使用标签,并且我们可以重写它的一些属性(下面的代码就重写了它的id):

            
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3. android:orientation="vertical" 
  4. android:layout_width="fill_parent" 
  5. android:layout_height="fill_parent"> 
  6. <include android:id="@+id/new" layout="@layout/share">include> 
  7. LinearLayout> 

如果在我们的布局中只需要使用共享布局的内容,这时候就可以用merge标签,这样使得布局更加高效灵活。

            
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <merge xmlns:android="http://schemas.android.com/apk/res/android" 
  3. <include android:id="@+id/newone" layout="@layout/share">include> 
  4. <include android:id="@+id/newtwo" layout="@layout/share">include> 
  5. merge> 

有了标签,很容易就能做到共享和重用布局,可是很多情况下,一个布局中有很多View并不常用,这就造成了资源的浪费,android为此提供了ViewStub标签来解决这个问题。在默认情况下ViewStub下的标签都有visibility=GONE属性(不可见),更重要的是在这个标签下的内容不会占用任何的空间。其实ViewStub和include类似,不过区别就在于ViewStub只会在你需要的时候进入你的界面,viewStub通过inflate()方法来通知系统加载其内部的View。这样就可以让我们既享受到的便利,又不会产生过多没用的View。 还是看个例子:

其中share.xml前面已经介绍过了,main.xml的布局文件:

            
  1. <?xml version="1.0" encoding="utf-8"?> 
  2.  2  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.  3     android:orientation="vertical" 
  4.       android:layout_width="fill_parent" 
  5.       android:layout_height="fill_parent" 
  6.       > 
  7.    <Button 
  8.       android:id="@+id/show" 
  9.       android:layout_width="wrap_content" 
  10.      android:layout_height="wrap_content" 
  11.      android:text="点击导入" 
  12.      /> 
  13.   <ViewStub    
  14.      android:id="@+id/viewStub"    
  15.      android:layout="@layout/share"    
  16.      android:layout_width="wrap_content"    
  17.      android:layout_height="wrap_content"    
  18.      />   
  19.   LinearLayout> 

MyViewStub.java代码:

            
  1. package com.notice520.viewstub;  
  2.    
  3.    import android.app.Activity;  
  4.    import android.os.Bundle;  
  5.   import android.view.View;  
  6.   import android.view.ViewStub;  
  7.   import android.view.View.OnClickListener;  
  8.   import android.widget.Button;  
  9.     
  10.  public class MyViewStub extends Activity {  
  11.        
  12.      private ViewStub mViewStub;  
  13.      private Button   showButton;  
  14.        
  15.      /** Called when the activity is first created. */ 
  16.      @Override 
  17.      public void onCreate(Bundle savedInstanceState) {  
  18.          super.onCreate(savedInstanceState);  
  19.          setContentView(R.layout.main);  
  20.            
  21.          mViewStub = (ViewStub)findViewById(R.id.viewStub);//实例化ViewStub控件,这里可以看出我们必//须为ViewStub设定id  
  22.          showButton = (Button)findViewById(R.id.show);  
  23.            
  24.          /*为按钮添加点击监听事件,后面的章节会介绍*/                           
  25.          showButton.setOnClickListener(new OnClickListener(){  
  26.                
  27.              @Override 
  28.              public void onClick(View v) {  
  29.                  if (mViewStub != null) {    
  30.                     mViewStub.inflate();  //点击即导入ViewStub标签的内容  
  31.                    }    
  32.              }  
  33.          });  
  34.      }  
  35.  } 

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

android UI进阶之布局的优化(二)_第3张图片 android UI进阶之布局的优化(二)_第4张图片

好了,今天就写到这了。希望对大家有帮助,有问题可以留言交流。欢迎转载,但是请注明出处。

更多相关文章

  1. android UI进阶之仿iphone的tab效果
  2. [置顶] Android 界面滑动实现---Scroller类 从源码和开发文档中
  3. Android中的通知和自定义通知布局
  4. 代码中进行RelativeLayout布局的修改添加
  5. Android使用ConstraintLayout布局设置TextView基线对齐
  6. H5 通过 input 标签,调起 Android 手机相册,点击取消时手机卡住

随机推荐

  1. android camera 竖直拍照 获取竖直方向照
  2. Android(安卓)去掉系统默认提示音、移除
  3. Android(安卓)UI性能优化(一)
  4. android中的dp、px、dip相关概念
  5. kotlin 实现一个简单 Android(安卓)路由(2
  6. Android开发中使用sqlite实现新闻收藏和
  7. Android获取内置sdcard跟外置sdcard路径
  8. 通过分析Google的todo-mvp深度解析Androi
  9. Android中选项卡TabHost的实际应用篇
  10. Android绘图机制(四)——使用HelloCharts开