Android布局优化

布局优化 与include merge 还有viewstub有关,分别有适用场景和需要注意的点,下面一一表述

ViewStub

ViewStub是一个轻量级View,也是一个初始化不做任何事情的View,但是它对应一个布局文件,然后可以在手动调用ViewStub.inflate()或者ViewStub.setVisibility(Visible)的时候将布局文件inflate,当前视图树会把ViewStub remove掉把对应的布局layout加入进但钱视图树。

ViewStub的应用场景,我遇到的情况是需要根据数据的不同展示不同的布局,但是布局的主体结构是一样的,只有一些不太一样,而且这些不一样的view嵌套比较深,比较复杂,所以适合用viewstub去代替,因为这样就不会消耗inflate的资源。

一个View是根据比如我们根据条件在动态加载View或者某个布局时,最通常就是把可能用到的View都写在布局上,然后可见性都设置为View.GONE 。之后在代码中动态更改其可见性,虽然操作简单,但是耗费资源,因为View.GONE在inflate布局仍会inflate,仍会创建对象,会被实例化,会被设置属性。而我推荐做法是用android.view.ViewStub,它指定一个布局时会被inflate和实例化,但是不占布局位置,占用资源少。当ViewStub所指向的布局被设置为可见,或者是调用了ViewStub.inflate()时,ViewStub所在的布局才会进行inflate之后实例化,然后ViewStub的布局属性传给它所指定的布局。当然,ViewStub的使用还是有缺点的,并不是任何时候都可以用。

ViewStub使用限制:

1、ViewStub只能被inflate一次,之后ViewStub对象就会被置为空,就从view层次上移除了,也就是说它所指定的布局被inflate之后,就不能再通过ViewStub去控制这个布局了;

2、ViewStub只能用来inflate一个布局文件,而不能是某一个具体的View,这时我们要做的是可以将View写在一个布局中;

3、ViewStub目前还不支持merge标签。

考虑到以上ViewStub的特点,再结合我自身的开发过程中,可以考虑到使用的ViewStub时主要有以下的情形:

当需要在运行时不止一次的显示和隐藏某一个布局时,ViewStub不可用,因为它只能够inflate一次,之后就会被置为空。这时只能采用View的可见性来控制了。

想要控制的是一个布局文件,而非View,ViewStub指定的是一个布局id,而非一个View对象。

当在使用ViewStub的布局属性时,某些属性是加在ViewStub上面,而不是加在实际的布局上面,这样才会起作用。而ViewStub的属性在inflate之后会都传给相应的布局。其中有个属性android:inflatedId 指是的可以使用它来重写包含布局文件的根元素的id。而在ViewStub上设定的layout_* 参数将会应用到包含的布局文件的顶部。

Include

include是在如果一个布局被多次重复使用的情况下,为了避免多次构建同样的布局,比如app导航栏,错误页面等,就可以把这些布局抽取出来,然后使用的时候直接include就行了。它和viewstub有本质区别,viewstub自带懒加载功能,能节省inflate消耗的资源,而它仅仅只是代码重用。

include需要注意的一些点是

(1)使用include最常见是找不到findViewById查找不到目标控件,应通过include的id来获取目标布局中子控件,当include指定了id,而你的layout也指定了id,则你的layout中的id会被覆盖。如果没有include的id,那么可以使用layout的id。

(2)其次,在include标签中所有的android:layout_*都是有效的,但前提是必须要写layout_width和layout_height两个属性

Merge

标签存在的意义是帮助标签排除多余的一层ViewGroup容器,减少view hierarchy的结构,提升UI performance。Developers官网举了一个很好的例子,大家可以自行查看一下,总结其意思就是,在主界面中,标签的parent ViewGroup与包含的layout根容器ViewGroup是相同的类型,那么则可以将包含的layout根容器ViewGroup使用标签代替,从而减少一层ViewGroup的嵌套,从而提升UI性能渲染。例如你的主布局文件是垂直布局,引入了一个垂直布局的include并且引入的布局没有针对父视图属性时,这时如果include布局使用的LinearLayout就会没有意义,使用的话会重复有两个LinearLayout布局,这样的话会增多无必要的UI层次的布局,这时就可以用\标签进行优化成一个LinearLayout

除此之外,merge也可以不跟include一起使用,可以单独使用一个merge标签为根节点的布局文件,但是需要在代码中手动inflate(int resource, ViewGroup root, boolean attachToRoot),将其置于一个ViewGroup中,同时设置attachToRoot为true,这样会将merge为根节点的布局add到viewgroup中。

Merge的属性是否生效?


借鉴了很多http://www.jianshu.com/p/0b1ac2620422这里面的东西,为了记录自己的学习。

你可能感兴趣的:(Android布局优化)