在开发中UI布局是我们都会遇到的问题,随着UI越来越多,布局的重复性、复杂度也会随之增长,我们怎样布局才是最合理,性能最好的呢?Android官方也给出了很多优化布局的方案,下面我主要讲解include
、merge
、ViewStub
在优化布局中的使用方法
include
include想必大家最熟悉了,它的用处就是当我们有一个布局在很多地方都用到的时候,比如divider
,toolbar
,我们可以将这个布局抽离出一个单独的xml文件,然后在其他需要用到它的时候include进来即可,简单来说就是布局重用,下面贴一个简单的例子toolbar.xml
|
|
这里的toolbar就是被抽离出来的布局,这样我们在其他Activity需要加入toolbar的时候直接includetoolbar.xml
就可以了
merge
merge标签的作用在于通过减少view的层级从而消除冗余ViewGroup,达到布局优化的目的.下面举一个购物车列表的例子
- 当购物车为空时,显示
view_order_none.xml
- 当购物车不为空时,显示列表ListView
下面贴一下布局文件的源码fragment_cart.xml,方便大家理解
|
|
这里fragment_cart.xml
包含了两个布局,ViewStub
(下面会介绍)和ListView
,他们通过一个FramLayout包裹起来,其实我们再仔细一想,这个FrameLayout的存在有没有必要呢?结果是没有必要的,它只会让我们层级又多了一层,这个时候就可以用merge
标签替换它了,这也是merge
的使用场景,用merge替换后的代码如下
|
|
ViewStub
ViewStub标签最大的优点是当你需要时才会加载,使用他并不会影响UI初始化时的性能。各种不常用的布局像进度条、显示错误消息等可以使用ViewStub
标签,以减少内存使用量,加快渲染速度。继续上面购物车列表为空的例子
判断ViewStub是否加载
|
|
上面我们是通过vs_cart_none.setVisibility(View.VISIBLE);
来加载ViewStub的布局的,还有另外一种方法
FrameLayout stub_fl;
...
ViewStub vs_cart_none = (ViewStub) findViewById(R.id.vs_cart_none);
if(stub_fl==null){
//加载购物车布局
stub_fl = (ListView)vs_cart_none.inflate();
}else{
}
注意这两种加载方法的判断逻辑是不一样的
还有一点 我们的ViewStub布局中有这个么一个属性,android:inflatedId=”@+id/stub_fl”,在判断ViewStub是否加载的第一种方法中,我们是通过这个inflatedId
来找到FrameLayout的,开始我也举得很疑惑,我们的FrameLayout不是有自己的idstub_fl
吗?为什么要通过这个inflatedId
来找,如果这两个id同时存在,该通过那个id来找,带着疑问我们去看下ViewStub的源码;
|
|
所以如果ViewStub属性中设置了android:inflatedId:stub_fl
,那么view_order_none.xml
中的android:id="@+id/fl_cart_none"
就无效了,否则就可以通过fl_cart_none
取到
总结
通过上面的介绍,我想大家应该大概了解include、merge、VIewStub的使用方法了,其实并不是有多难,只是我们很少用他们而已,我们在做性能优化优化的时候,UI布局的优化也是其中的一部分,那么让我们用上它们吧!
参考
http://developer.android.com/intl/zh-cn/training/improving-layouts/reusing-layouts.html
http://www.devtf.cn/?p=509