android如何对布局优化,Android性能优化:XML布局优化

进行Android应用开发时,界面布局也会对应用程序的性能产生比较大的影响,假如布局写得糟糕的话,那么程序加载UI的速度就会非常慢,从而造成不好的客户体验。因而,写出更高效、更优雅的布局是非常重要的。那么本篇文章我们就来学习一下,如何通过优化布局来提高应用程序的性能。

首先第一点:重用布局文件,减少不必要的代码。

有些时候我们可能需要反复利用某个已经写好的布局,假如你重复写这部分代码一方面是没有任何意义,另一方面会提高维护的难度。而Android当然也已经充分考虑到了布局重用的重要性,于是提供了include和merge这两个非常有用的标签:

include

include 标签可以允许在一个布局当中引入另外一个布局,那么比方说我们程序的所有界面都有一个公共的部分,这个时候最好的做法就是将这个公共的部分提取到一个独立的布局文件当中,而后在每个界面的布局文件当中通过使用include来引用这个公共的布局。这样既提高了我们的工作效率,也会给程序更好的可维护性和更好的性能。

例如APP中每个界面都有一个头部(包括两个按钮,标题)时,加入每个界面我们都写上同样的布局,这会加大我们的工作量,同时进行的也是少量没有什么意义的重复性工作,假如需要改动头部时,可维护性也是极差。这个时候即可以将头部抽离出来,写成一个独立的头部XML文件,而后通过标签引入到每一个布局文件中:头部文件如下所示

0faa6804fda34c6b4270f627f5ca979f.png

当其余界面需要用到这个头部时,我们要做的非常简单,比方activity_main2.xml中要用到只要要这样写,如下所示:

f27d8fbf0efa72c30f1906584e1255f6.png

标签当中可以指定一个layout属性,我们在这个layout属性中填写需要引入的布局名即可以了。而且使用这种引入的方式,以后假如titlebar的界面有所变更,我们只要要修改titlebar_layout.xml这一个文件即可以了,而不是所有界面一个个地去修改。到这里不知道你有没有发现问题?仔细看看上方的图片哟!你会发现 布局文件中的 “您好”不见了,并没有在界面中呈现出来,为什么呢?你再往回看看头部文件就知道了。

出现这个问题是起因是由于titlebar_layout的最外层布局是一个宽高都是match_parent的RelativeLayout,它会将整个布局都填充满,因此我们本来的布局也就看不见了。那既然问题的起因清楚了,相信你立刻就想到应该怎样修改了,将RelativeLayout的layout_height属性修改成wrap_content不即可以了嘛。没错,这样修改当然是没问题的,不过这种修改方式会让所有引用titlebar_layout的界面都受到影响,而如何你只希望让activity_main2.xml这一个界面受影响的话,那么可以使用覆写属性的方式。

4ada304e072e79d43418a32283107c16.png

在标签当中,我们是可以覆写所有layout属性的,即include中指定的layout属性将会覆盖掉titlebar_layout中指定的layout属性,可以看到这样修改后,界面显示就正常啦。

除了layout_height之外,我们还可以覆写任何一个layout属性,如layout_gravity、layout_margin等,而非layout属性则无法在标签当中进行覆写。另外需要注意的是,假如我们想要在标签当中覆写layout属性,必需要将layout_width和layout_height这两个属性也进行覆写,否则覆写效果将不会生效。

第二点:使用merge标签减少布局嵌套。

merge

在标签中的控件自身没有布局属性,默认会继承父控件的布局属性。它的主要作用是为了防止在引用布局文件时产生多余的布局嵌套。大家都知道,Android去解析和展现一个布局是需要消耗时间的,布局嵌套的越多,那么解析起来就越耗时,性能也就越差,因而我们在编写布局文件时应该让嵌套的层数越少越好。

上方所说的include标签有好处,但也会有不足,就是可能会让布局的嵌套层级变得更复杂更多。比方我们写一个布局,如下所示:

36a03e64a3739a23327fe7a6215f9b3b.png

而后将这个布局使用include标签引入到Activity中去。

cfbfcf92c58c0d3710992bb34e2b79c0.png

看上去是不是感觉没有什么问题?是滴,看着的确没问题,但实际上已经存在了多余的嵌套了。

66b784f5ff72c9689c4f2d7933cf11d1.png

很容易看到,最外层首先是一个FrameLayout,不知道为什么最外层是FrameLayout的朋友可以去查看一下(系统自动增加的)。而后FrameLayout中包含的是一个LinearLayout,这个就是我们最外层的布局(activity_main3.xml)。接下来的部分就有问题了,在最外层的LinearLayout当中包含了两个元素,一个是EditText,另一个又是一个LinearLayout,而后在这个内部的LinearLayout当中才包含了两个按钮。

其实,这个内部的LinearLayout就是一个多余的布局嵌套,实际上并不需要这样一层,让两个按钮直接包含在外部的LinearLayout当中即可以了。而这个多余的布局嵌套其实就是因为布局引入所导致的,由于我们在引入的布局文件中也定义了一个LinearLayout。此时使用merge标签来优化,修改another.xml中的代码,如下所示:

12e23cec1e449490916b9b2b0cae1b3d.png

此时的层级为:

1a099f4c36fd33287a901e0fd137fe67.png

其实这里我们只是将根布局换成merge标签,这就表示当有任何一个地方通过include引入这个布局时,会将merge标签内包含的内容直接填充到include的位置,而且不会再增加任何额外的布局结构,有效的减少了布局的嵌套。

第三点:正当使用style文件,定义各个控件的通用属性,减少重复代码。

比方文字的属性设置、布局属性设置等:

eee796bdc3e421d8fa0f6c4a0c966455.png

而后直接使用就ok了。

第四点:使用ViewStub来完成那些只要要在特定情况下显示的布局。

项目中有时候会有这样一种需求,当满足某某某条件的时候,就会显示某一个东西(布局),不满足时则将其隐藏。看到这种需求可能马上就会想到使用属性INVISIBLE或者者GONE进行隐藏,而后当客户需要使用这些元素的时候再把它们置成VISIBLE显示出来。这种方式的确可以实现我们想要的效果,尽管简单但是这种方式的性能就很一般了,使用这种方式尽管隐藏了布局,但是它们实际上是存在布局当中的,它们的属性也都是存在的,在解析布局的时候同样会将它们解析出来,系统在加载布局的时候这一部分还是会将其绘制出来,同样花费绘制时间,而我们却不需要,这就肯定程度上影响了我们的性能。怎样处理呢?

Android为此给我们提供了一种非常轻量级的控件——懒加载布局ViewStub。ViewStub虽说也是View的一种,但是它没有大小,没有绘制功能,也不参加布局,资源消耗非常低,将它放置在布局当中基本可以认为是完全不会影响性能的。使用方式如下:

在布局文件中使用ViewStub来加载需要隐藏的布局:

9a09fc3d1bee71d034929e7297731429.png

而后在需要显示的时候,如下调用ViewStub viewStub = (ViewStub) findViewById( R.id.view_stub ); if( null != viewStub ){ /* 主要是这一句显示更多布局 */ View view = viewStub.inflate(); /* 布局文件中的控件 */ EditText name1 = (EditText) view.findViewById( R.id.et_name1 ); }

这样就实现效果了。另外需要提示大家注意的一点是:

ViewStub所加载的布局是不可以使用标签的,因而这有可能导致加载出来的布局存在着多余的嵌套结构,这种情况下我们需要正当取舍,而对于那些隐藏的布局文件结构相当复杂的情况,使用ViewStub还是一种相当不错的选择的,即便添加了一层无用的布局结构,依然还是利大于弊。

第五点:正当使用分割线布局

我们在写布局的时候,有时候需要写分割线来进行上下的隔离,我们通常会用组件来绘制出分割线,如下所示:

be99584d5df1171c46fc380c1b5de51b.png

其实我们可以使用 LinearLayoutCompat(v7包中的) 组件来实现线性布局元素之间的分割线,从而减少了使用View来实现分割线效果。

LinearLayoutCompat其实就是LinerLayout组件,只是为了兼容低版本,所以你必需引用 v7包下面的LinearLayoutCompat。 LinearLayoutCompat除了拥有LinerLayout本来的属性之外,主要通过如下几种属性来实现 间隔线效果:

app:divider=”@drawable/line” 给分隔线设置颜色,这里你需要在drawable中去定义shape资源,否则将没有效果。看下面

9a92585473549b02755fb145b90f3501.png

app:dividerPadding=”20dp” 给分隔线设置距离左右边距的距离。

app:showDividers=”middle|beginning|end” 分隔线显示的位置,有四种参数值:middle指在 每个item之间,beginning 指在最顶端显示分隔线,end 指在最底端显示分隔线,none则代表不显示间隔线。

组件距离分割线的距离在组件中设置就好了。

注意 这三个属性需要使用 xmlns:app=”http://schemas.android.com/apk/res-auto” 命名空间。

下面我们来看看效果:

ed9ab2cbc52cda43266789602a601e93.png

到这我们对布局的优化就已经差不多了,还有一点就是我们可以正当的减少LinearLayout,更多的使用RelativeLayout来进行界面布局,这样可以减少许多不必要的层级。

最后感谢大家能看到这,希望能带给大家帮助!

同时也希望各位可以帮忙点个赞,转发分享一下,谢谢大家的支持!

简书点赞可以有好几种赞,长按点赞按钮就会有选项,大家点赞的时候,麻烦点个超赞~在这先谢谢您的支持啦!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值