Android性能优化之布局优化
1、考虑UI的渲染机制,人眼能感觉的流畅画面帧数需要达到40帧每秒到60帧每秒,也就是最佳fps在60fps左右。1000ms/60fps,系统每次渲染的时间保持在16ms之内,UI界面才会是非常流畅的,也就是说onDraw方法要避免执行大量的操作,同时还不要做耗时的操作,才能保证这个标准。
2、避免过度绘制(Overdraw),过度绘制会很浪费cpu,GPU资源,例如系统已经默认绘制了Activity的背景,再给布局绘制重叠的背景,默认的Activity的背景就属于无效的过度绘制。
3、布局层级的控制,Android中,系统对view的测量,布局,和绘制都是通过View树的遍历进行操作的。View树太高,就会影响这些的速度,布局优化尽量降低View树的高度,Google在API文档中建议View树的高度不宜超过10层。多中布局的合作使用,降低View层数。在降低层级这里include和merge的使用也可以起到很大作用,在第四点具体讲。
4、嵌套过多的无用布局,这里用到Include,比如那种共通的UI,Topbar,Bottombar,为了后期好维护,降低程序的冗余度,会选择使用include。
但是在使用include的时候,你想在include布局中覆盖原布局中的android:layout_xxxx的属性,必须在原始布局中指定属性<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:orientation="vertical" android:layout_height="match_parent"> <include layout="@layout/lala" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
同时在使用include的时候,总会看到<merge>标签。<merge>标签一般与<include>标签使用是为了减少布局的层数。上面的布局中已经是一个竖直方向的LinearLayout了。下面的布局中的LinearLayout一看就是多余的,通过merge标签就可以去掉多余的那一层LinerLayout。<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:gravity="center" android:textSize="30sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="gang"/> </LinearLayout>
<merge xmlns:android="http://schemas.android.com/apk/res/android"> <TextView android:gravity="center" android:textSize="30sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="gang"/> </LinearLayout> </merge>5、ViewStub的使用,实现View延迟加载,啥时候用啥时候加载。
<ViewStub>是一个非常轻量级的组件,不仅不可见,且大小为0.ViewStub初始的时候不会显示,在需要的时候才会渲染它,不是一次加载布局全部渲染出来,更加能够提高布局的效率。
<ViewStub android:layout_width="match_parent" android:layout="@layout/lala" android:layout_height="wrap_content" />ViewStub和其他组件一样
mViewStub=(ViewStub)findViewById(R.id.a);有两种方法可以让ViewStub显示出来,第一种是
mViewStub.setVisibility(View.VISIBLE);第二种是:
View infalterview=mViewStub.inflate(); TextView oo=(TextView)infalterview.findViewById(R.id.tet1); oo.setText("gang");二者的区别是第二中可以通过方法找到view里面的控件,添加点击事件等。