二,减少布局层级
1,drawable属性的使用.
这布局都熟悉吧,基本上APP都会用到类似布局.常见的布局方式:
<LinearLayout
android:id="@+id/lin_feedback"
android:layout_width="match_parent"
android:layout_height="@dimen/my_item_height"
android:background="@drawable/white_ripple"
android:gravity="center_vertical"
android:paddingLeft="@dimen/margin_space"
android:paddingRight="@dimen/margin_space">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="4dp"
android:background="@drawable/icon_feedback"/>
<TextView
style="@style/A16_Font_333"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_weight="1"
android:text="意见反馈"/>
<ImageView
style="@style/LayoutWrapStyle"
android:background="@drawable/enter_arrow"/>
</LinearLayout>
而使用drawable属性只要一个TextView就能搞定.对,你没看错,只用一个TextView,看代码:
<TextView
style="@style/A16_Font_333"
android:layout_width="match_parent"
android:layout_height="48dp"
android:drawablePadding="@dimen/dp_8"
android:gravity="center_vertical"
android:drawableLeft="@drawable/icon_feedback"
android:drawableRight="@drawable/enter_arrow"
android:text="意见反馈"/>
主要使用 drawableLeft 和 drawableRight 属性来代替 ImageView 放左右图drawablePadding来控制文字和图标的间距,既提高性能,又减少代码,就问你酸爽不酸爽!
2,RelativeLayout 和 LinearLayout 的选择.
关于这两者的使用选择:在不增加层级的情况下使用LinearLayout.否则使用RelativeLayout以达到减少层级的目的. 那么为什么不都用RelativeLayout呢.因为RelativeLayout的爹也是个LinearLayout(笑哭).详见Android中RelativeLayout和LinearLayout性能分析
3,别再纠结 RelativeLayout 和 LinearLayout ,看大招.
Google 2016年I/O大会新推出约束布局 ConstraintLayout ,号称布局终结器.妈妈再也不用担心复杂布局影响性能了!关于约束布局,谁用谁知道,我用我懵逼…..新东西总是不习惯,慢慢会好的.详见郭神 Android新特性介绍,ConstraintLayout完全解析
三,提高加载速度ViewStub
ViewStub使用场景
在开发项目中经常碰到一些在指定条件下才需要加载的layout,比如网络异常页面.你可以仅在需要的时候载入它们,提高 UI 渲染速度。这时就可以使用ViewStub !!!
ViewStub使用方法
ViewStub 通过设置 android:layout 属性来指定需要被 inflate 的 Layout 类型。
xml中:
<ViewStub
android:id="@+id/vs_loading_abnormity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="@layout/loading_hint" />
注意: android:layout_width和android:layout_height必须设置 不然不会显示. 这是与include标签不一样的地方,include是可以用layout里的布局属性.而ViewStub只能自己布局属性.
代码中:
ViewStub vsLoadingHint = (ViewStub) window.findViewById(vs_loading_hint);
if (vsLoadingHint != null) {
hintView = vsLoadingHint.inflate();
}
注意: inflate()只能执行一次,所以要多处调用时注意判断是否已加载.由于ViewStub执行inflate后被@layout/loading_hint替换,故vsLoadingHint再次findViewById时会返回null.所以用vsLoadingHint != null来判断是否inflate().
四,合并布局merge
在复用布局时我们都会用到include.layout里的布局是全搬过来的.而如果在当前布局中的ViewGroup和layout的一致时,就会造成布局层级的浪费.这时就要用merge合并布局了.具体用法见代码:
activity XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="@+id/view_statistics"
layout="@layout/include_my_item"/>
</LinearLayout>
include_my_item XML
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<TextView
style="@style/A16_Font_333"
android:layout_width="match_parent"
android:layout_height="48dp"
android:drawablePadding="@dimen/dp_8"
android:gravity="center_vertical"
android:drawableLeft="@drawable/icon_feedback"
android:drawableRight="@drawable/enter_arrow"
android:text="意见反馈"/>
<TextView
style="@style/A16_Font_333"
android:layout_width="match_parent"
android:layout_height="48dp"
android:drawablePadding="@dimen/dp_8"
android:gravity="center_vertical"
android:drawableLeft="@drawable/icon_feedback"
android:drawableRight="@drawable/enter_arrow"
android:text="关于我们"/>
</merge>
其他性能布局技巧
Space的使用
Space顾名思义就是一个间隔距离的控件.当你需要空白控件来占位空间,又不想使用margin的时候.就用到Space了.为啥不用View呢.是因为Space的Draw方法是空的.不绘制任何东西,这样就可以节省资源,提高性能.用法:
<android.support.v4.widget.Space
android:layout_width="match_parent"
android:layout_height="12dp"/>
优雅的分割线
布局中分割线很常用,怎么告别繁琐的View,优雅的绘制一个分割线呢?
快来试试使用LinearLayout的divider和showDividers属性吧.废话不说,直接上码:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:divider="@drawable/divider"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:showDividers="middle">
<TextView
android:layout_width="match_parent"
android:layout_height="48dp"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:text="个人信息"/>
<TextView
android:layout_width="match_parent"
android:layout_height="48dp"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:text="关于我们"/>
</LinearLayout>
divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<size android:height="2dp"></size>
<solid android:color="@color/colorAccent"></solid>
</shape>
效果图:
-
showDividers属性有4个值:
-
none:不显示分隔线
beginning:开始处显示分隔线
end:结尾处显示分隔线
middle:每两个组件间显示分隔线
尽量用match_parent
在布局时,尽量使用match_parent,因为wrap_content需要测量计算本身的尺度.而match_parent是匹配父容器的尺度,所以只要测量计算父容器就行,减少一次测量计算,从而提高性能.