分享

Android一些你需要知道的布局优化技巧

 醉初丶 2016-11-18

唯鹿的博客地址:

http://blog.csdn.net/qq_17766199




今天分享一些layout布局书写中的一些技巧,希望看过之后你也一样可以写出性价比高的布局。我个人的目标是用最少的View写出一样效果的布局。因为我相信View的数量减少伴随着的就是层级的减少。从而达到结构清晰,渲染速度快的效果。顺着这个逻辑,我将优化分为重用、合并、按需载入。


1
重用< include/="">
   

< include="">标签可以在一个布局中引入另外一个布局,这个的好处显而易见。类似于我们经常用到的工具类,随用随调。便于统一修改使用。

举例说明:首先写一个公共的布局title_bar.xml,app中常用的标题栏。




预览:



下来activity_main.xml调用它:




运行后效果和预览一样一样的。当然我们也可以在< include="">标签当中重新设置宽高等layout属性。


2

合并

   

减少嵌套

首先我们心中要有一个大原则:尽量保持布局层级的扁平化。在这个大原则下我们要知道:

  • 在不影响层级深度的情况下,使用LinearLayout而不是RelativeLayout。因为RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,才会让子View调用2次onMeasure。Measure的耗时越长那么绘制效率就低。

  • 如果非要是嵌套,那么尽量避免RelativeLayout嵌套RelativeLayout。这简直就是恶性循环,丧心病狂。

实现方法就不细说了,大家都是明白人。

< merge/="">

< merge/="">主要用来去除不必要的FrameLayout。它的使用最理想的情况就是你的根布局是FrameLayout,同时没有使用background等属性。这时可以直接替换。因为我们布局外层就是FrameLayout,直接“合并”。

举例说明:比如上面用到的activity_main.xml文件,我们通过View Hierarchy工具看一下,如图:



可以看到,最外层是FrameLayout,下来我们修改一下。




再次查看:

很明显少了一层RelativeLayout,当然运行效果是一样的。当然如果我们不需要title_bar.xml中的绿色背景,那么可以这样修改。




运行效果:



运行查看层级,如下图:

结果很明显。


3

用TextView同时显示图片和文字

   

这个我就不细说了,举一个我们项目中的一个例子,代码一看便知。

首先要完成的效果是如下图:



这种效果很常见,一般实现方法是这样。(貌似没人这样写吧,哈哈)




效果图:



那么我们优化一下:




你没有看错,少了两个ImageView和去除嵌套LinearLayout。效果不用说一样一样的。当然EditView等也一样的,还有属性drawableBottom和drawableTop供你使用。同时利用代码setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom)可以让我们动态去设置图片。


4

使用TextView的行间距

   

先上我们需要实现的效果图:



效果很简单,实现代码




这里我偷懒了多嵌套了一层LinearLayout,但。。。这不重要,我先直接修改。

优化后代码:




老规矩,效果一样一样的。可以看到我们仅仅利


Android:lineSpacingExtra='8dp'这一行代码就省去了3个TextView,如果行数更多呢?是不是方便多了。


其中:lineSpacingExtra属性代表的是行间距,他默认是0,是一个绝对高度值。同时还有lineSpacingMultiplier属性,它代表行间距倍数,默认为1.0f,是一个相对高度值。


我们来使用一下:




当然了这两条属性可以同时使用,查看源码可以知道,他们的高度计算规则为mTextPaint.getFontMetricsInt(null) * 行间距倍数 + 行间距。


5

使用Spannable或Html.fromHtml

   

这里也是举例说明,比如下图效果:



如果实现上图红框中的效果,笨办法就是写三个TextView,“¥”,“价格”,“门市价”分别实现,其实用一个TextVIew就可以实现,类似如下代码:




同样Html.fromHtml也可以实现。这样不就减少了两个TextView了。



6
按需载入ViewStub
   

在开发中经常会遇到这样的情况,会在程序运行时动态根据条件来决定显示哪个View或某个布局。那么通常做法就是把用到的View都写在布局中,然后在代码中动态的更改它的可见性。但是它的这样仍然会创建View,会影响性能。

这时就可以用到ViewStub了,ViewStub是一个轻量级的View,不占布局位置,占用资源非常小。

例子:比如我们请求网络加载列表,如果网络异常或者加载失败我们可以显示一个提示View,上面可以点击重新加载。当然一直没有错误时,我们就不显示。




hint_view.xml就是这个提示View,可以根据情况自己写。


用法




用法很简单,记得一旦ViewStub可见或是被inflate了,ViewStub就不存在了,取而代之的是被inflate的Layout。所以它也被称做惰性控件。


7

用LinearLayout自带的分割线

   

还记得上文用TextView同时显示图片和文字中的例子吗?我们可以看到每个条目之间都是有一根分隔线的,那么怎么实现呢?别人我不知道,反正我原来是用一个View设置高度实现的。相信一定有人和我一样。

那么老办法我就不演示了,直接上代码:




效果图:



实现的核心部分其实是LinearLayout的这两行。

android:divider='@drawable/divider'android:showDividers='middle'

其中divider.xml是分隔线样式。




showDividers 是分隔线的显示位置,beginning、middle、end分别代表显示在开始位置,中间,末尾。

还有dividerPadding属性这里没有用到,意思很明确给divider添加padding。感兴趣可以试试。


8

Space控件

   

还是接着上面的例子,如果要给条目中间添加间距,怎么实现呢?当然也很简单,比如添加一个高10dp的View,或者使用android:layout_marginTop='10dp'等方法。但是增加View违背了我们的初衷,并且影响性能。使用过多的margin其实会影响代码的可读性。

这时你就可以使用Space,他是一个轻量级的。

实现代码与效果:





防止过度绘制

  • http://blog.csdn.net/lmj623565791/article/details/45556391

参考

  • http://www./2015/01/19/android-layout-optimize


总结

最后想想如果没有用这些技巧,我们要写多少代码,多少View?效果是不是杠杠的!其实上面说了这么多,具体的情景使用还是要看项目的具体情况,在性能面前有些还是要取舍的,但千万不能为了优化而优化。优化也是不断积累的过程,不要指望立竿见影。愿大家都能写出一手漂亮的布局。




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约