android 性能优化之布局

Android 性能优化之布局


Android 基本的五大布局,LinearLayout、FrameLayout、RelativeLayout、AbsoluteLayout和TableLayout,前三种布局常用到。其中FrameLayout效率最高,LinearLayout次之,RelativeLayout消耗最多,但功能最强大。FrameLayout是里面包含的控件,一层一层叠加放置,属性最少,除了通用的marginLeft marginTop marginStart等几个属性,只有一个,gravity,控制里面的view的所在的位置。FrameLayout一般用到根节点,比如视频播放,有暂停、快进等,此时用帧布局最合适。再有一些图片,要一个个显示,此时也适合用帧布局。
 
 <?xml version="1.0" encoding="utf-8"?>  
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:gravity="center">  
    <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" 
android:background="#ff000000" android:gravity="center" android:text="1"/>  
    <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" 
android:background="#ff654321" android:gravity="center" android:text="2"/>  
     <TextView android:layout_width="50dp" android:layout_height="50dp" 
android:background="#fffedcba" android:gravity="center" android:text="3"/>  
 </FrameLayout>  

LinearLayout是线性布局,可以设置水平或竖直,里面的控件view是一个挨着一个,默认是水平。LinearLayout中的子元素属性android:layout_weight,它用于子元素在剩余空间中占有的大小比例。如果一行中有两个等长的文本框,weight值可以是同为1。如果一行中有两个不等长的文本框,那么他们的android:layout_weight值分别为1和2,并且android:layout_width="fill_parent",那么第一个文本框将占据剩余空间的三分之二,第二个文本框将占据剩余空间中的三分之一;如果android:layout_width="0dp"时,两个框的宽度相反,第一个占三分之一,第二个占三分之二。权重属性导致LinearLayout内部绘制两次,降低效率,所以尽量不要用此属性。LinearLayout一般用于布局的根节点,布局内部分为n个模块,模块之间无关联,纯粹的一个接一个,模块一般用RelativeLayout,功能强大。

RelativeLayout 相对布局,适合作为一个模块的容器,经常是用第一个放入的view为标准,其他的控件在它的基础上摆放,经常用的属性
android:layout_toLeftOf —— 该组件位于引用组件的左方
    android:layout_toRightOf —— 该组件位于引用组件的右方
    android:layout_above —— 该组件位于引用组件的上方
    android:layout_below —— 该组件位于引用组件的下方
       android:layout_alignParentLeft —— 该组件是否对齐父组件的左端
       android:layout_alignParentRight —— 该组件是否齐其父组件的右端
       android:layout_alignParentTop —— 该组件是否对齐父组件的顶部
       android:layout_alignParentBottom —— 该组件是否对齐父组件的底部
    android:layout_centerInParent —— 该组件是否相对于父组件居中
    android:layout_centerHorizontal —— 该组件是否横向居中
    android:layout_centerVertical —— 该组件是否垂直居中
有一点要说明,LinearLayout里面的view不可能重叠在一起,而RelativeLayout中的布局是可以重叠的。

布局优化,最主要的是层级的优化,一般而言,优秀的app标准是普通布局层级嵌套不要超过三层,这样在绘制布局才能快速,并且findViewById时,才能迅速找到对应的view,缩短时间。有的布局嵌套六七层,这时候就要想办法拼命减少层级了。ListView和RecyclerView嵌套item时,item布局越少越好,效果越明显。很容易碰到一个问题是item的宽度和高度显示的不太正确,前面博客讲解LayoutInflater 时提过,当时提了两种解决方法,

一  使用 Inflate(resId , parent, false )方法;

二  在item的跟布局上在加上一层布局,相对布局或线性布局都行,
android:layout_width="match_parent"
android:layout_height="match_parent"
当我们追求技术时,当然选择第一种方案,不要随意的增加布局层数。并且刷新listview时,做到局部刷新,这样程序更快,更省内存。


布局优化,接下来是view的运用,比如要显示一个ImageView和一个TextView,我们完全可以利用TextView的属性,拔这两个view用一个TextView来显示,提高效率。再有就是使用自定义控件,把一些控件用view来绘制出来,提高效率。一般控件上下之间有分割线时,我们都会用view来实现,其实在LinearLayout中,我们可以用LinearLayoutCompat来代替LinearLayout,向下兼容,直接绘制出分割线,写个shape,设置属性引用。 
<android.support.v7.widget.LinearLayoutCompat
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center|center_horizontal"
            android:orientation="vertical"
            app:divider="@drawable/line"
            app:showDividers="middle|beginning|end">
line是用xml写的shape,
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/blue" />
    <!--需要设置高度,否则不显示-->
    <size android:height="1px" />
</shape>


布局优化,还有几个小杀器,include,merge和ViewStub 三个标签,include 是重用,比如每个页面都有title布局,布局一样,位子内容不一样,使用include,在activity中设置标题名;merge是减少层级意思,意思是里面包含的view和merge的父容器使用一个布局属性,例如你的主布局文件是LinearLayout竖直布局,里面包含引入了一个LinearLayout竖直布局,此时,可以把里面的这个LinearLayout替换为merge,相当于merge不在了,但布局xml看着清晰;ViewStub 最大的优点是当你需要时才会加载,平时是一个不可见的view。尤其是注册需要填xt,此时使用ViewStub 特别合适。


布局优化的另一个领域就是过度绘制了。
设置—->开发者选项—->显示GPU过度绘制,按不同颜色值来显示布局的过度绘制,绘制的层次从最优到最差:蓝,绿,淡红,红。前三种还能接受,第四种就不行了,要想办法优化,降低过度绘制有几种方法:
一、每个activity都有默认的背景,window会被默认添加一个纯色的背景,我们可以 getWindow().setBackgroundDrawable(null);去掉背景色。
二、layout布局中,根节点的背景色能去掉就去掉,尽量不要重合。ListView如果铺满屏幕,item有背景色,则Listview的背景色和根节点的背景色都可以去掉。
三、我们使用ViewPager+Fragment模式,如果每个Fragment都有背景色,则Activity中的可以省略。
四、用好现有的控件属性,比如Listview的分割线,尽量少在item里面重新绘制,可以使用list.setDevice()方法设置。
五、在写自定义控件view时,onDraw()方法要用好,绘制时尽量不要重叠绘制。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值