在平时设计UI时,相信大多数人用得比较多的布局就是LinearLayout和RelativeLayout了,毕竟这两种布局能实现我们一般的需求。还记得刚开始学Android时,使用Eclipse进行开发,每次新建一个布局文件,该布局文件默认使用的布局是LinearLayout。后来改用Android Studio开发,SDK版本更新之后,每次新建的布局文件改成用RelativeLayout作为默认布局了。 很多人说这个Google团队出于性能考虑而进行的优化,的确,RelativeLayout能减少布局嵌套从而提高布局的性能,而使用Linearlayout如果不注意的话可能出现布局嵌套层次太深,从而大大降低了布局的性能。但是LinearLayout真的比不上RelativeLayout吗?答案是否定的。          View的绘制一般都是经过onMeasure,onLayout,和onDraw,LinearLayout和RelativeLayout都是继承自ViewGroup,而ViewGroup又是继承View的,所以LinearLayout和RelativeLayout一般也会经历上面所说的三个流程。但是在ViewGroup一般默认不调用onDraw,因为ViewGroup是容器,一般只用来装载控件,所以负责测量控件总共所需的宽高,并将控件放在我们指定的位置就行了。所以接下来我打算只从onMeasure和onLayout两个方面对比LinearLayout和RelativeLayout。     

    先看看LinearLayout的onMeasure方法:


      我们都知道LinearLayout有两个方向走向,一个是竖直方向,一个是水平方向。可以看出Linearlayout在测量宽高时是根据我们设置的方向分别调用不同的测量方法,这两个测量方法大致一样,我们以measureVertical来说明LinearLayout的具体测量过程吧。因为measureVertical这个方法有点长,所以我们贴部分代码说明问题就行了。


    在measureVertical方法里面调用了这个方法,什么意思呢?我们都知道在LinearLayout中,我们可以使用layout_weight属性,当子View使用了layout_weight属性时就会调用这个方法,这个方法的大概步骤是先不限制设置了weight属性的子View的大小,只要容器剩余的空间还足够就不对该子View作处理,但凡事都有个度,所以不可能每个设置了weight属性的子View都无限大吧,所以当所有子View测量完毕后,会对设置了weight属性的子View再调用一次measure方法,如下:



    接下来说说RelativeLayout的onMeasure方法,部分源码如下:





    由上面源码我们可知RelativeLayout对子View分别进行了竖直和水平方向的两次测量,这不难理解,因为RelativeLayout里面每个子View的位置都是相对的,所以要分别从水平和竖直两个方向对子View进行测量。
    接下来在来看看LinearLayout和RelativeLayout的onLayout方法。同样的,先看LinearLayout的onLayout方法,如下:


    简单分析这个方法,即先根据LinearLayout设置的方向调用不同的方法,和上面的onMeasure方法中调用的情况类似,在这两个方法做的事情也差不多,就是将子View逐个按照其大小和布局参数摆放在对应的位置。
    再看看RelativeLayout中onLayout方法,如下:

          RelativeLayout的onLayout方法和LinearLayout的onLayout方法类似,都是遍历所有的子View,逐个逐个地将子View放在对应的位置,所以两者的onLayout方法性能相差不大。
    总结:LinearLayout和RelativeLayout的性能差别主要体在onMeasure方法上,RelativeLayout始终要从竖直和水平两个方向对子View进行测量,而Linearlayout,当我们没有在子View中使用layout_weight属性时,LinearLayout只需对子View进行一次测量,反则需要对子View进行两次测量以确定最终大小,所以如果可以我们尽量少用layout_weight属性。在使用这两个布局之前,我们可以先进行衡量,如果需要实现的布局嵌套层次不深或者嵌套层次已经固定了,可以考虑用LinearLayout,相对的,如果某个布局嵌套层次很深,此时应该考虑使用RelativeLayout来减少嵌套层析从而优化布局的性能。



更多相关文章

  1. Android(安卓)ListView的背景和黑色边缘化的问题
  2. 利用ActivityInstrumentationTestCase2测试Activity
  3. android开发之Parcelable使用详解
  4. android sample之Notepad(带下划线的TestView)
  5. Android设置中“强行停止”详解
  6. Android绘图基础:Canvas、Paint等的使用
  7. android中URI简介
  8. Android多媒体开发(4)——添加FFmpeg支持
  9. Android(安卓)动态设置列表样式,不用ListView或者RecyclerView

随机推荐

  1. android导入老项目出现的问题和解决办法
  2. android代码混淆报错总结:java.io.IOExce
  3. Android设备获取默认的启用数据卡的SubId
  4. android适配器之基于BaseAdapt自定义简单
  5. 修改 android 手机 hosts 文件的方法
  6. Android(安卓)GridView 分页加载数据
  7. Android(安卓)总结外置 内置SD卡路径问题
  8. android 浮动按钮
  9. Android实现按下Back键程序隐藏到后台,而
  10. android listview的下拉加载