遵循Android Layout优化的两段通用代码

四个小Tip:

1.尽量不要使用Linelayout,使用Relativelayout替换。android:layout_alignWithParentIfMissing只对Relativelayout有用,如果那个视图设置为gone,这个属性将按照父视图进行调整。

2.对于使用Adapter的控件,如List,使用递归太深的布局,会严重影响性能。 

3.对于Textview和Imageview组成的Layout,直接使用Textview替换(DrawableTop类似属性)。 

4.对于父Layout是FrameLayout的,如果子Layout也是FrameLayout,可以将FrameLayout替换为merge,这样可以减少一层递归深度。


其中一个就是关于Layout的优化就是关于:<merge/>标签在UI界面中的优化作用,跳转过去看看就好了。


如何优化Android layout(UI)性能


悲剧回顾:

记得之前有一个项目,前期的layout设计几乎到处都是里三层外三层的各种嵌套。这样的布局实现效果与美工的效果图虽然相差无几,但到了后期,令人难以接受的悲剧发生了——一些配置较低的手机只要运行在layout嵌套较深的界面上,总会出现卡顿现象,若有输入控件,激活输入法时,也会引起程序crash……


悲剧之由来:

我们得始终坚信:有果必有因。

1. 初学时养成的潜意识:不考虑性能,先看效果。大家可能是这样学习的,想快点掌握其实现方法,性能或优化等方面的问题,留着以后再考虑。可是,何时才是“以后”呢?

2. 没有深入理解各种layout运用:怎么方便就怎么来,例如使用LinearLayout进行多层嵌套即可轻松实现复杂的布局。

3. 没太留意用户体验感受:随着时间推移,手机配置越来越高,人们已经很难从感知上去判别layout的加载速度会带来什么样的体验。有时候,即使能感觉到有一点点的有问题,也会轻易放过自己:没关系。

4. 有意识,但不熟悉优化:有时候知道会有问题,但不知道如何判断其优劣,不清楚如何下手,缺少思路与方法等。


Layout优化大致思路:

1. 尽可能消耗较少的系统资源:包括时间,内存,电量等。

2. 尽可能流畅,不给人卡顿,加载慢,等待时间过长,干等无操作的尴尬体验等。


如何对症下药?

我们大概清楚上述的因果后,就得对具体案例进行对症下药,加深理解,进而举一反三。这回我们不能为所欲为了!

那么如何优化呢?下面是一个简单的例子,演示优化步骤及思路:

1. 优化前的一个3层级的layout:

<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/LinearLayout1"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:orientation="vertical"
	android:paddingBottom="@dimen/activity_vertical_margin"
	android:paddingLeft="@dimen/activity_horizontal_margin"
	android:paddingRight="@dimen/activity_horizontal_margin"
	android:paddingTop="@dimen/activity_vertical_margin"
	>

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:gravity="center"
       >

       <TextView
           android:id="@+id/account"
           android:layout_width="wrap_content"
           android:layout_height="60dp"
           android:gravity="center_vertical"
           android:text="账号:"
           />

       <EditText
           android:id="@+id/accountInput"
           android:layout_width="200dp"
           android:layout_height="60dp"
           android:gravity="center_vertical"
           android:hint="请输入账号"
           />

   </LinearLayout>

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="60dp"
       android:gravity="center"
       >

       <TextView
           android:id="@+id/pwd"
           android:layout_width="wrap_content"
           android:layout_height="60dp"
           android:gravity="center_vertical"
           android:text="密码:"
           />
       
       <EditText
           android:id="@+id/pwdInput"
           android:layout_width="200dp"
           android:layout_height="60dp"
           android:gravity="center_vertical"
           android:hint="请输入6位以上的密码"
       />
   </LinearLayout>
   
</LinearLayout>

其实,在手机上运行这个layout,我们的感官并不能觉察到有什么不妥或不好的体验。所以,我们得通过第三方工具Hierarchy View查看其性能参数:

从上图很直观地看到:这是一个4层级的layout;在id为content的节点上读取其性能数据:
Measure:0.562ms
Layout:0.287ms
Draw:2.212ms

同时,也计算了一下setContentView(R.layout.nested_layout)的时间:42ms。

06-16
15:21:35.869:
D/MainActivity(4739):
 setContentView(R.layout.nested_layout), takeTime:42ms
计算代码如下:

private static final String TAG = "MainActivity";
private long start = 0;
private long takeTime = 0;

@Override

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    start = System.currentTimeMillis();
    setContentView(R.layout.nested_layout);
    takeTime = System.currentTimeMillis() - start;
    Log.d(TAG,"setContentView(R.layout.nested_layout), takeTime:" + takeTime + "ms");

}


就是这么一个简单的UI布局,上面的性能指示器就有3个为红色,暂且(在没有对比之前)认为效果并不是很好。
具体分析:
1. 这里使用了3个容器(LinearLayout),都是用于控制子元素的显示方向;
2. 想想上面的优化思路,尽可能减少时间,内存的开销:在实现同样效果的情况下,容器越多,加载实例化容器,计算,布局,绘制的操作相应地会消耗更多的时间与内存。
3. 如果我们使用较少的容器实现一样的效果,这不就是优化性能了吗?
4. 我们的RelativeLayout不就可以做得到吗?


2. 采用RelateLayout优化后的layout

<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/LinearLayout1"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
>

   <RelativeLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:gravity="center"
       >
   
       <TextView
           android:id="@+id/account"
           android:layout_width="wrap_content"
           android:layout_height="60dp"
           android:layout_alignParentLeft="true"
           android:gravity="center_vertical"
           android:text="账号:"
           />

       <EditText
           android:id="@+id/accountInput"
           android:layout_width="200dp"
           android:layout_height="60dp"
           android:layout_toRightOf="@id/account"
           android:gravity="center_vertical"
           android:hint="请输入账号"
           />

       <TextView
           android:id="@+id/pwd"
           android:layout_width="wrap_content"
           android:layout_height="60dp"
           android:layout_below="@id/account"
           android:gravity="center_vertical"
           android:text="密码:"
           />
       
       <EditText
           android:id="@+id/pwdInput"
           android:layout_width="200dp"
           android:layout_height="60dp"
           android:layout_below="@id/accountInput"
           android:layout_toRightOf="@id/pwd"
           android:gravity="center_vertical"
           android:hint="请输入6位以上的密码"
           />

   </RelativeLayout>

</LinearLayout>



很明显,我们减少了一个容器,其中的2个LinearLayout被一个RelateLayout代替,性能指示器也没有出现红色。在同样的节点处性能参数如下:
Measure:0.443ms
Layout:0.060ms
Draw:1947ms

同样,计算setContentView(R.layout.optimized_layout)花费的时间:36ms

各指标都比原来提高了。

事情还没完,是不是总觉得夹在FrameLayout与RelateLayout之间的LinearLayout有点多余呢?我RelateLayout干嘛要经过你LinearLayout呢,如果真的非要经过你,你能说说你在这里的有用之处吗?


3. 去除没必要层级:

再请来一个大神对第2步的layout进行检查与评判——Lint:


从上图红圈中的提示内容可知:id为LinearLayout1的容器是没有必要存在的。所以这次的优化得去掉这没必要的层级。

<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:gravity="center"
	android:paddingBottom="@dimen/activity_vertical_margin"
	android:paddingLeft="@dimen/activity_horizontal_margin"
	android:paddingRight="@dimen/activity_horizontal_margin"
	android:paddingTop="@dimen/activity_vertical_margin"
>



	<TextView
	android:id="@+id/account"	
	android:layout_width="wrap_content"	
	android:layout_height="60dp"
	android:layout_alignParentLeft="true"	
	android:gravity="center_vertical"	
	android:text="账号:"	
	/>
		
	<EditText	
	android:id="@+id/accountInput"	
	android:layout_width="200dp"	
	android:layout_height="60dp"	
	android:layout_toRightOf="@id/account"	
	android:gravity="center_vertical"	
	android:hint="请输入账号"	
	/>
		
	<TextView	
	android:id="@+id/pwd"	
	android:layout_width="wrap_content"	
	android:layout_height="60dp"	
	android:layout_below="@id/account"
	android:gravity="center_vertical"	
	android:text="密码:"
	/>

	<EditText	
	android:id="@+id/pwdInput"	
	android:layout_width="200dp"	
	android:layout_height="60dp"	
	android:layout_below="@id/accountInput"	
	android:layout_toRightOf="@id/pwd"
	android:gravity="center_vertical"	
	android:hint="请输入6位以上的密码"	
	/>

</RelativeLayout>

清楚地看到,性能指示器一片绿,相比于优化前:我们原来需要解掉3件“衣服”,现在只需要解掉一件就可以看到你想要的,你说这速度能不快吗?到此,前面的暂且可以去掉了!

小结:

1. 性能指示器,优化layout的参考方向。

2. 有效利用Lint工具,进行优化,他不仅仅应用于layout的优化,还包括code的优化,总之其功能非常强大!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值