安卓中的布局优化之clude、merge、ViewStub

1.include

include标签常用于将布局中的公共部分提取出来供其他layout共用,以实现布局模块化,也是平常我们设计布局时用的最多的。

需要注意的是如果一个根布局引入多个include需要每个include加上id的属性,在代码中使用的时候要先通过id找到inclued标签。

include_text_relative.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:gravity="center_horizontal"
              android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="@string/textview"
        android:textSize="24sp"/>
 

</LinearLayout>

根布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:gravity="center_horizontal"
              android:orientation="vertical">
 <include
        android:id="@+id/include_text2"
        layout="@layout/include_text_relative"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="50dp"/>
</LinearLayout>

代码

View view_include_Relative = findViewById(R.id.include_text2);
TextView view_textView_relative = (TextView) view_include_Relative.findViewById(R.id.textView);
view_textView_relative.setText("");

2.merge

merge标签主要用于辅助include标签,在使用include后可能导致布局嵌套过多,多余的layout节点或导致解析变慢(可通过hierarchy viewer工具查看布局的嵌套情况)

官方文档说明:merge用于消除视图层次结构中的冗余视图,例如根布局是Linearlayout,那么我们又include一个LinerLayout布局就没意义了,反而会减慢UI加载速度
include_text_relative.xml


<merge	xmlns:android="http://schemas.android.com/apk/res/android"
            >

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="@string/textview"
        android:textSize="24sp"/>
 

</merge>

根布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:gravity="center_horizontal"
              android:orientation="vertical">
 <include
        android:id="@+id/include_text2"
        layout="@layout/include_text_relative"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="50dp"/>
</LinearLayout>

这里就减少了一个线性布局减少了UI的渲染。

注意:
1.因为merge标签并不是View,所以在通过LayoutInflate.inflate()方法渲染的时候,第二个参数必须指定一个父容器,且第三个参数必须为true,也就是必须为merge下的视图指定一个父亲节点.
2.因为merge不是View,所以对merge标签设置的所有属性都是无效的.
3.如果include的layout用了merge,调用include的根布局也使用了merge标签,那么就失去布局的属性了
4.merge标签必须使用在根布局
5.ViewStub标签中的layout布局不能使用merge标签

3.ViewStub

ViewStub 标签最大的优点是当你需要时才会加载,使用它并不会影响UI初始化时的性能.各种不常用的布局像进度条、显示错误消息等可以使用ViewStub标签,以减少内存使用量,加快渲染速度.ViewStub是一个不可见的,实际上是把宽高设置为0的View.效果有点类似普通的view.setVisible(),但性能体验提高不少


<ViewStub  
    android:id="@+id/stub_import"  
    <!--android:inflateId:重写ViewStub的父布局控件的Id-->
    android:inflatedId="@+id/panel_import"  
    < <!--android:layout:设置ViewStub被inflate的布局-->
    android:layout="@layout/progress_overlay"  
    android:layout_width="fill_parent"  
    android:layout_height="wrap_content"  
    android:layout_gravity="bottom" />  


      //setVisibility()方式加载布局,加载次数不限
    ((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);  
     //inflate()方式加载布局,只能加载一次
    View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();  

需要注意:ViewStub标签不支持merge标签,ViewStub的inflate只能被调用一次,第二次调用会抛出异常,setVisibility可以被调用多次,但不建议这么做(ViewStub 调用过后,可能被GC掉,再调用setVisibility()会报异常)。

你可能感兴趣的:(安卓)