接上文:Android性能优化之布局篇(一)
这布局都熟悉吧,基本上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来控制文字和图标的间距,既提高性能,又减少代码,就问你酸爽不酸爽!
关于这两者的使用选择:在不增加层级的情况下使用LinearLayout.否则使用RelativeLayout以达到减少层级的目的. 那么为什么不都用RelativeLayout呢.因为RelativeLayout的爹也是个LinearLayout(笑哭).详见Android中RelativeLayout和LinearLayout性能分析
Google 2016年I/O大会新推出约束布局 ConstraintLayout ,号称布局终结器.妈妈再也不用担心复杂布局影响性能了!关于约束布局,谁用谁知道,我用我懵逼…..新东西总是不习惯,慢慢会好的.详见郭神 Android新特性介绍,ConstraintLayout完全解析
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().
在复用布局时我们都会用到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顾名思义就是一个间隔距离的控件.当你需要空白控件来占位空间,又不想使用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,因为wrap_content需要测量计算本身的尺度.而match_parent是匹配父容器的尺度,所以只要测量计算父容器就行,减少一次测量计算,从而提高性能.