布局优化——include、merge 、ViewStub

在项目开发中,UI布局是我们都会遇到的问题,如果布局过于复杂,层级过深,不仅会影响阅读性,还会导致性能降低。Android官方给了几个优化的方法include、merge、ViewStub。这里我们我们简单的介绍下使用方法,注意事项,并从源码角度分析他们的好处,注意事项。

布局重用标签

标签是我们最常用的标签,能够重用布局文件。把一套布局封装起来,使用的时候使用include标签引入即可:

include布局文件:include_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rcv_container"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
       android:id="@+id/recycler_view"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:gravity="center"/>

</LinearLayout>

使用:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/content_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <View
        android:id="@+id/divider"
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="@color/biz_business_select_poi_bg" />

    <include layout="@layout/include_layout.xml" />
    //可以使用id、layout_width、layout_height属性
    <!--<include -->
        <!--android:id="@+id/recycler_list"-->
        <!--android:layout_height="match_parent"-->
        <!--android:layout_width="match_parent"-->
        <!--layout="@layout/biz_common_pull_refresh_recyclerview"/>-->
</LinearLayout>

include标签使用很简单但是需要注意以下两点: 

  1. 标签若指定了ID(recycler_list)属性,这个id会将会覆盖你的include_layout中定义了的ID(rcv_container)属性;所以当用findViewByid(R.id.rcv_container)方法是找不到根View的,而应该使用findViewByid(R.id.recycler_list)如果不加以注意会报空指针异常。
  2. 在include标签中所有的Android:layout_*都是有效的,前提是必须要写layout_width和layout_height两个属性

减少View层级标签

布局结构应尽量要避免多层次的嵌套来减少开销,数量应最多不要超过10层。

标签可以减少多余的层次结构,在UI的结构优化中起着非常重要的作用。多用于替换FrameLayout或者当一个布局包含另一个时,标签消除视图层次结构中多余的视图组。例如你的主布局文件是垂直布局,引入了一个垂直布局的include,这是如果include布局使用的LinearLayout就没意义了,使用的话反而减慢你的UI表现。这时可以使用标签优化。

如果将include_layout.xml文件中的改成标签,再通过标签引入到上面的布局中,系统忽略节点并且直接添加RecyclerView到父容器中。

<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rcv_container"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
       android:id="@+id/recycler_view"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:gravity="center"/>

</merge>

懒加载标签

ViewStub标签最大的优点是当你需要时才会加载,使用他并不会影响UI初始化时的性能。各种不常用的布局想进度条、显示错误消息等可以使用ViewStub标签,以减少内存使用量,加快渲染速度。ViewStub是一个不可见的,大小为0的View,相当于一个“占位控件”。然后当ViewStub被设置为可见的时或调用了ViewStub.inflate()的时候,ViewStub所指向的布局就会被inflate实例化,且此布局文件直接将当前ViewStub替换掉,然后ViewStub的布局属性(layout_margin***、layout_width等)都会传给它所指向的布局。这样,就可以使用ViewStub在运行时动态显示布局,节约内存资源。

标签使用如下:

<ViewStub  
    android:id="@+id/stub_import"  
    android:inflatedId="@+id/panel_import"  
    android:layout="@layout/include_layout" //替换ViewStub的layout资源文件 
    android:layout_width="fill_parent"  
    android:layout_height="wrap_content"  
    android:layout_gravity="bottom" /> 

在代码中调用:

((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);  
// or  
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();  
ViewStub名字猜测,它应该用了代理,以后再分析。

当调用inflate()函数的时候,ViewStub被引用的资源替代,并且返回引用的view。 这样程序可以直接得到引用的view而不用再次调用函数findViewById()来查找了。

注:ViewStub目前有个缺陷就是还不支持  标签。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值