布局优化

布局优化之include

  • 如果一个布局会在很多地方都被用到,那么我们可以使用这个标签,新建一个XML文件,假设叫my_include_layout,在其他布局使用,代码如下

    <include
    android:id="@+id/my_include_layout"
    layout="@layout/my_include_layout" />
    

    但是在写的时候有以下几个地方需要注意:

    1. 如果我们在其他应用的地方对我们的标签进行了命名,那么在标签里面的命名将失效即被调用者的命名覆盖
    2. 如果我们想要对标签进行权重比例分配,那么权重标签是必须定义在标签实现里面的,调用的地方是没有这个属性的。
    3. 标签里面的实现就是我们普通的布局文件,普通布局文件拥有的属性标签文件都有

布局优化之merge

  • merge标签主要是为了减少布局层级的,常见的主要有以下几种使用情况。

    1. 如果一个布局的根布局的层级属性是FrameLayout,那么,我们可以直接略去,使用merge标签对布局文件进行书写。这样可以减少层级
    2. 如果一个布局文件的外部布局是LinearLayout,内部布局又是一个Linearlayout,那么,内部的布局文件再加这个标签其实就是多余,这时候我们就可以使用merge标签,在XML文件中调用的时候就采用include同样的方式。

布局优化之ViewStub

  • ViewStub标签其实也就是懒加载标签模式,由于ViewStub其实是个宽高都为0的一个View,默认值是看不见的,所以只有每次需要的时候使用setVisibility 或者 Inflate 的时候才会加载,使用这个标签不是影响UI初始化的性能。使用ViewStub标签承载的对象一般是那种不常用的布局文件,比如进度条,显示错误消息等,使用这个标签可以减少内存使用量,加快渲染进度。标签使用样式如下:

    <ViewStub  
        android:id="@+id/stub_import"  
        android:inflatedId="@+id/stub_comm_lv"  
        android:layout="@layout/my_comment_layout"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:layout_gravity="bottom" />  
    

当我们想加载布局时,有两种方法,同时也对应两种判断一个布局文件是否已经被加载的方法,代码示例如下:

//方式一:
ViewStub listStub = (ViewStub) findViewById(R.id.stub_import);  
// 加载评论列表布局  
listStub.setVisibility(View.VISIBLE);  
// 获取到评论ListView,注意这里是通过ViewStub的inflatedId来获取  
    ListView commLv = findViewById(R.id.stub_comm_lv);  
        if ( listStub.getVisibility() == View.VISIBLE ) {  
               // 已经加载, 否则还没有加载  
        }  
    }  
   } 

//方式二:
ViewStub listStub2 = (ViewStub) findViewById(R.id.stub_import) ;  
    // 成员变量commLv2为空则代表未加载  
    if ( commLv2 == null ) {  
    // 加载评论列表布局, 并且获取评论ListView,inflate函数直接返回ListView对象  
      commLv2 = (ListView)listStub2.inflate();  
    } else {  
    // ViewStub已经加载  
    }  

ViewStub使用有几个需要注意的地方:

  1. iewStub也有一个缺陷,那就是不支持merge属性

  2. 判断是否已经加载过, 如果通过setVisibility来加载,那么通过判断可见性即可;如果通过inflate()来加载是不可以通过判断可见性来处理的,而需要使用方式2来进行判断。

  3. findViewById的问题,注意ViewStub中是否设置了inflatedId,如果设置了则需要通过inflatedId来查找目标布局的根元素。