本篇文章为Android优化的布局部分,该部分应该是Android中很重要的,不管是在自定义控件中,仍是在简单的书写布局时,都应该尽可能遵循一些优化原则,这样布局的绘制效率才会更高,体验才能更好。
java
Layout结构若是太复杂,Android的绘制过程就会很复杂,measure过程就会很复杂,我分析的View绘制机制中详细介绍了整个测量、布局和绘制过程,过于复杂、嵌套的布局会形成性能问题。android
嵌套的 LinearLayout 可能会使得 View 的层级结构很深。使用LinearLayout时,一般咱们喜欢用嵌套的布局来动态设置一个View的Visibility ,因为LinearLayout是线性的,所以即便隐藏一个View也不会影响到其它View的排列。而在RelativeLayout中,View的位置都是相对于其它View的,所以,隐藏以后,会致使以前的View没有参考对象了,致使的相对位置改变,这时你可使用alignWithParentIfMissing=”true”来处理这种状况。git
此外,嵌套使用了 layout_weight 参数的 LinearLayout 的计算量会尤为大,由于每一个子元素都须要被测量两次。这对须要屡次重复 inflate 的 Layout 尤为须要注意,好比使用 ListView 或 GridView 时。github
在使用了include后可能致使布局嵌套过多,出现没必要要的layout节点,从而致使解析变慢。设计模式
merge标签可用于两种典型状况:api
好比,若是你有一个 Layout 是一个竖直方向的 LinearLayout,其中包含两个连续的 View 能够在别的 Layout 中重用,那么你会作一个 LinearLayout 来包含这两个 View ,以便重用。不过,当使用另外一个 LinearLayout 来嵌套这个可重用的 LinearLayout 时,这种嵌套 LinearLayout 的方式除了减慢你的 UI 性能外没有任何意义。网络
为了不这种状况,你能够用
|
|
如今,当你要将这个 Layout 包含到另外一个 Layout 中时(而且使用了
若是你的程序 UI 在不一样地方重复使用某个 Layout,那本节教你如何建立高效的,可重用的 Layout 部件,并把它们“包含”到 UI Layout 中。测试
为了高效重用整个的 Layout,你可使用
除了简单的把一个 Layout 包含到另外一个中,你可能还想在程序开始后,仅当你的 Layout 对用户可见时才开始载入。
ViewStub 是一个轻量的视图,不须要大小信息,也不会在被加入的 Layout 中绘制任何东西。每一个 ViewStub 只须要设置 android:layout 属性来指定须要被 inflate 的 Layout 类型。viewstub经常使用来引入那些默认不会显示,只在特殊状况下显示的布局,如进度布局、网络失败显示的刷新布局、信息出错出现的提示布局等。
如下 ViewStub 是一个半透明的进度条覆盖层。功能上讲,它应该只在新的数据项被导入到应用程序时可见。
|
|
载入 ViewStub
当你要载入用 ViewStub 声明的 Layout 时,要么用 setVisibility(View.VISIBLE) 设置它的可见性,要么调用其 inflate() 方法。
下面以在一个布局main.xml中加入网络错误时的提示页面network_error.xml为例。main.mxl代码以下:
|
|
其中network_error.xml为只有在网络错误时才须要显示的布局
setVisibility(View.VISIBLE)方式
|
|
inflate方式
|
|
注意:
inflate() 方法会在渲染完成后返回给被 inflate 的视图,因此你不须要再调用 findViewById() 去查找这个元素。减小inflate的次数,也会对效率有一点提高。
而setVisible方式还须要再次findViewById找到ViewStub中的元素。
一旦 ViewStub 可见或是被 inflate 了,ViewStub 元素就不存在了。取而代之的是被 inflate 的 Layout,其 id 是 ViewStub 上的 android:inflatedId 属性。(ViewStub 的 android:id 属性仅在 ViewStub 可见之前可用)
注意:ViewStub 的一个缺陷是,它目前不支持使用
若是你有一个包含复杂或者每一个项 (item) 包含不少数据的 ListView ,那么上下滚动的性能可能会下降。本节给你一些关于如何把滚动变得更流畅的提示。
保持程序流畅的关键,是让主线程(UI 线程)不要进行大量运算。你要确保在其余线程执行磁盘读写、网络读写或是 SQL 操做等。为了测试你的应用的状态,你能够启用 StrictMode。
你应该把主线程中的耗时间的操做,提取到一个后台线程中,使得主线程只关注 UI 绘画。
使用convertView、
你的代码可能在 ListView 滑动时常用 findViewById(),这样会下降性能。即便是 Adapter 返回一个用于回收的 convertView,你仍然须要查找这个元素并更新它。避免频繁调用 findViewById() 的方法之一,就是使用 View Holder(视图占位符)设计模式。
ViewHolder 存储了标签下的每一个视图。这样你不用频繁查找这个元素:
|
|
而后,在 Layout 的类中生成一个 ViewHolder 对象:
|
|
这样你就能够轻松获取每一个视图,而不是用 findViewById() 来不断查找视图,节省了宝贵的运算时间。
由于每一条Item移入屏幕的时候,都会调用getView,不要在getView中作复杂的操做,不要频繁的建立对象。Item点击的处理不要提早作。特别是在快速滑动的时候,会致使频繁的调用getView。
尽可能使用RelativeLayout,能够减小层级的嵌套。
慎用LinearLayout的layout_weight属性,可使用RelativeLayout的centerHorizontal=”true”、toLeft、toRight代替
为了便于识别,你能够根据本身的业务来对当前界面的资源进行命名,好比当前是登录界面,那么你能够这样命名:
login_edit_username
login_edit_password
login_btn_submit
login_txv_forgot_pass
ic_action_add, ic_action_location (ActionBar Icons)
ic_play, ic_save (General Icons)
ic_tab_music, ic_tab_more (Tab Icons)
对style.xml和dimens.xml的命名能够通用的尽可能通用,由于一个项目的基本视图不少都是通用的,好比ActionBar、ListView等,规范通用的命名能够很方便的移植到其它项目中。
|
|