上午看了篇UI优化技巧的文章,《Android Layout Tricks #3: Optimize by merging》是关于标签的使用,经常看到别人源码的布局文件使用到这个标签,感觉很好奇,今天看了下android文档的表述以及示例有所了解。

   的出现是为了优化android布局,减少视图树的层级。当LayoutInflater遇到这个标签时,它会跳过它,并将内的元素添加到的父元素里,从而达到减少层级。这里先看一个简单的布局文件。  

 

   
   
   
   
  1. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  2.     android:layout_width="fill_parent" 
  3.     android:layout_height="fill_parent" > 
  4.  
  5.     <ImageView 
  6.         android:layout_width="fill_parent" 
  7.         android:layout_height="fill_parent" 
  8.         android:scaleType="center" 
  9.         android:src="@drawable/golden_gate" /> 
  10.  
  11.     <TextView 
  12.         android:layout_width="wrap_content" 
  13.         android:layout_height="wrap_content" 
  14.         android:layout_gravity="center_horizontal|bottom" 
  15.         android:layout_marginBottom="20dip" 
  16.         android:background="#AA000000" 
  17.         android:padding="12dip" 
  18.         android:text="Golden Gate" 
  19.         android:textColor="#ffffffff" /> 
  20.  
  21. FrameLayout> 

上面的根目录是FrameLayout,里面包裹着ImageView以及TextView两个标签。

效果如下图:

 

Android之Merge及自定义属性attrs.xml使用_第1张图片

使用HierarchyViewer 工具来查看该视图的层级效果,我们可以看到蓝色的矩形的就是我们刚刚的FrameLayout

的层数。

Android之Merge及自定义属性attrs.xml使用_第2张图片

将FrameLayout改成merge,代码如下:

 

   
   
   
   
  1. <merge xmlns:android="http://schemas.android.com/apk/res/android" 
  2.     android:layout_width="fill_parent" 
  3.     android:layout_height="fill_parent" > 
  4.  
  5.     <ImageView 
  6.         android:id="@+id/goldenIv" 
  7.         android:layout_width="fill_parent" 
  8.         android:layout_height="fill_parent" 
  9.         android:scaleType="center" 
  10.         android:src="@drawable/golden_gate" /> 
  11.  
  12.     <TextView 
  13.         android:layout_width="wrap_content" 
  14.         android:layout_height="wrap_content" 
  15.         android:layout_gravity="center_horizontal|bottom" 
  16.         android:layout_marginBottom="20dip" 
  17.         android:background="#AA000000" 
  18.         android:padding="12dip" 
  19.         android:text="Golden Gate" 
  20.         android:textColor="#ffffffff" /> 
  21.  
  22. merge> 

我们看到的效果是这样的,蓝色的是用来包含之前FrameLayout的父标签,

现在直接包裹着ImageView和TextView两个子标签

Android之Merge及自定义属性attrs.xml使用_第3张图片

这个就是merge的简单使用了。

下面再来一个实例,是自定义控件以及自定义属性的使用。

首先我们创建一个布局文件okcalcelbar_button.xml:

 

    
    
    
    
  1. xml version="1.0" encoding="utf-8"?> 
  2. <Button xmlns:android="http://schemas.android.com/apk/res/android" 
  3. android:layout_width="wrap_content" 
  4. android:layout_height="wrap_content"/> 


再创建一个okcancelbar.xml的文件:
 

 

    
    
    
    
  1. xml version="1.0" encoding="utf-8"?> 
  2. <merge xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:layout_width="wrap_content" 
  4.     android:layout_height="wrap_content" > 
  5.     <include  
  6.         layout="@layout/okcalcelbar_button" 
  7.         android:id="@+id/okcancelbar_ok" 
  8.         /> 
  9.     <include  
  10.         layout="@layout/okcalcelbar_button" 
  11.         android:id="@+id/okcancelbar_cancel" 
  12.         /> 
  13. merge> 

创建values下面创建自定义属性的文件attrs.xml

 

     
     
     
     
  1. xml version="1.0" encoding="utf-8"?> 
  2. <resources> 
  3.     <declare-styleable name="OkCancelBar">  
  4.         <attr name="okLabel" format="string"/>   
  5.        <attr name="cancelLabel" format="string"/>   
  6.     declare-styleable>   
  7. resources> 

说明:上面自定义属性文件中

OkCancelBar就是定义在OkCancelBar"> 里的 名字,获取里面属性用 名字_ 属性 连接起来就可以.TypedArray 通常最后调用 .recycle() 方法,为了保持以后使用该属性一致性!

接下来创建OkCancelBar类继承LinearLayout

 

     
     
     
     
  1. package com.xzw.merge; 
  2.   
  3. import android.content.Context; 
  4. import android.content.res.TypedArray; 
  5. import android.util.AttributeSet; 
  6. import android.view.Gravity; 
  7. import android.view.LayoutInflater; 
  8. import android.widget.Button; 
  9. import android.widget.LinearLayout; 
  10.  
  11. public class OkCancelBar  extends LinearLayout{ 
  12.     public OkCancelBar(Context context,AttributeSet attrs) { 
  13.          super(context,attrs); 
  14.          setOrientation(HORIZONTAL); //横排 
  15.          setGravity(Gravity.CENTER); //居中显示 
  16.          setWeightSum(1.0f); 
  17.           
  18.          LayoutInflater.from(context).inflate(R.layout.okcancelbar, this,true); 
  19.         //TypedArray是一个数组容器   
  20.          TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OkCancelBar, 00); 
  21.              
  22.             String text = array.getString(R.styleable.OkCancelBar_okLabel);//这里的属性是:名字_属性名   
  23.             if (text == null) text = "Ok"
  24.             ((Button) findViewById(R.id.okcancelbar_ok)).setText(text); 
  25.              
  26.             text = array.getString(R.styleable.OkCancelBar_cancelLabel); 
  27.             if (text == null) text = "Cancel"
  28.             ((Button) findViewById(R.id.okcancelbar_cancel)).setText(text); 
  29.              
  30.             array.recycle(); 
  31.     } 
  32.      

 

 

创建布局文件:

 

     
     
     
     
  1. xml version="1.0" encoding="utf-8"?> 
  2.  
  3. <merge 
  4.     xmlns:android="http://schemas.android.com/apk/res/android" 
  5.     xmlns:okCancelBar="http://schemas.android.com/apk/res/com.xzw.merge"> 
  6.  
  7.     <ImageView   
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="fill_parent"  
  10.      
  11.         android:scaleType="center" 
  12.         android:src="@drawable/golden_gate" /> 
  13.      
  14.     <com.xzw.merge.OkCancelBar 
  15.         android:layout_width="fill_parent"  
  16.         android:layout_height="wrap_content"  
  17.         android:layout_gravity="bottom" 
  18.         android:paddingTop="8dip" 
  19.         android:gravity="center_horizontal" 
  20.         android:background="#AA000000" 
  21.         okCancelBar:okLabel="Save" 
  22.         okCancelBar:cancelLabel="Don't save" /> 
  23.  
  24. merge> 

说明:
xmlns:okCancelBar:是我们自定义属性的命名空间前缀。也就是下面

  1.  okCancelBar:okLabel="Save" 
  2.  okCancelBar:cancelLabel="Don't save"

用到的。

”http://schemas.android.com/apk/res/com.xzw.merge" 其中com.xzw.merge 是类文件所在包名。

使用自定义属性必须加上该命名空间。

 

 

看下效果图:

Android之Merge及自定义属性attrs.xml使用_第4张图片

Android之Merge及自定义属性attrs.xml使用_第5张图片

上面就是完整的实例。下面附上代码。

能力有限请大家多多指教。