Android layout优化

在XML中定义Android的Layout时,有四个比较特别的标签是非常重要的,分别是<viewStub/>, <requestFocus />, <merge /> 和<include />,其中有三个是与资源复用有关。
1)<ViewStub />标签
ViewStub是一个不可见的,大小为0的View,最佳用途就是实现View的延迟加载,在需要的时候再加载View,和Java中常见的性能优化方法延迟加载一样。当调用ViewStub的setVisibility函数设置为可见或则调用inflate()方法初始化该View的时候,ViewStub引用的资源开始初始化,然后引用的资源会替代掉ViewStub,把自己填充在ViewStub的原位置。因此在没有调用setVisibility(int)或inflate()方法之前ViewStub会一直存在组件树层级结构中,但是由于ViewStub非常轻量级,这对性能影响非常小。可以通过ViewStub的inflatedId属性来重新定义引用的layout的id( 也就是说,加入我们所引用的layout的id是R.layout.prelayout,然后我们在ViewStub中添加属性android:inflatedId="@+id/subLayout“,那么我们就可以用R.layout.subLayout来引用这个layout了 )。

示例:
            <ViewStub android:id="@+id/stub"
            android:inflatedId="@+id/subLayout"
            android:layout="@layout/preLayout"
            android:layout_width="120dip"
            android:layout_height="40dip" />

上面定义的ViewStub我们可以通过findViewById(R.id.stub)来找到,在初始化资源preLayout后,ViewStub从父组件中删除,然后preLayout替代ViewStub的位置。初始资源preLayout得到的组件可以通过inflatedId 指定的id "subLayout"引用。 然后初始化后的资源被填充到一个120dip宽、40dip高的地方。

推荐使用下面的方式来初始化ViewStub:
 
     ViewStub stub = (ViewStub) findViewById(R.id.stub);
     View inflated = stub.inflate();
 
当调用inflate()函数的时候,ViewStub被引用的资源替代,并且返回引用的view。 这样程序可以直接得到引用的view而不用再次调用函数findViewById()来查找了。
:ViewStub目前有个缺陷就是还不支持 <merge /> 标签。

2)<include />标签
可以通过这个标签直接加载外部的xml到当前结构中,是复用UI资源的常用标签。
用法:将需要复用xml文件路径赋予include标签的Layout属性。

            <include android:id="@+id/cell1" layout="@layout/ar01" />
            <include android:layout_width="fill_parent" layout="@layout/ar01" />
注:
1.include标签只有layout属性是必须的<include layout="@layout/layout_ID"/>
2.include标签若指定了ID属性,而你的layout也定义了ID,则你的layout的ID会被覆盖
<include android:id="@+id/your_ID" layout="@layout/layout_ID"/>
3.在include标签中所有的android:layout_*都是有效的。但前提是必须要写layout_width和layout_height两个属性,否则无效 。

3)<requestFocus />标签
标签用于指定屏幕内的焦点View。
用法: 将标签置于Views标签内部

            <EditText id="@+id/text"
                         android:layout_width="fill_parent"
                         android:layout_height="wrap_content"
                         android:layout_weight="0"
                         android:paddingBottom="4">
                   <requestFocus />
            </EditText>

4)<merge />标签
它在优化UI结构时起到很重要的作用,目的是通过删减多余或者额外的层级,从而优化整个Android的Layout结构。
示例:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <ImageView android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:scaleType="center"
        android:src="http://ygc87.blog.163.com/blog/@drawable/icon" />
    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:layout_marginBottom="20dip"
        android:layout_gravity="center_horizontal|bottom" android:padding="12dip"
        android:background="#AA000000" android:textColor="#ffffffff"
        android:text="Golden Gate" />
</FrameLayout>
运行上边的layout,然后启动 tools> hierarchyviewer.bat工具查看当前UI结构视图:
android的layout定义时常用的标签 - ygc87 - 我的博客
 我们可以很明显的看到出现了两个framelayout节点,这两个意义完全相同的节点造成了资源浪费(这里可以提醒大家在开发工程中可以习惯性的通过hierarchyViewer查看当前UI资源的分配情况),那么如何才能解决这种问题呢(就当前例子是如何去掉多余的frameLayout节点),这时候就要用到<merge />标签来处理类似的问题了。我们将上边xml代码中的FrameLayout替换成merge:
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <ImageView android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:scaleType="center"
        android:src="http://ygc87.blog.163.com/blog/@drawable/icon" />
    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:layout_marginBottom="20dip"
        android:layout_gravity="center_horizontal|bottom" android:padding="12dip"
        android:background="#AA000000" android:textColor="#ffffffff"
        android:text="Golden Gate" />
</merge>
运行程序后在Emulator中显示的效果是一样的,可是通过hierarchyviewer查看的UI结构是有变化的,当初多余的 FrameLayout节点被合并在一起了,或者可以理解为将merge标签中的子集直接加到Activity的FrameLayout跟节点下(这里需要提醒大家注意:所有的Activity视图的根节点都是FrameLayout)。如果你所创建的Layout并不是用FrameLayout作为根节点(而是应用LinerLayout等定义root标签),就不能应用上边的例子通过merge来优化UI结构。
android的layout定义时常用的标签 - ygc87 - 我的博客
 

    * <merge />只可以作为layout的根节点。
    * 当需要扩充的layout本身是由merge作为根节点的话,需要将被导入的layout置于viewGroup中,同时需要设置attachToRoot为true。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值