本文翻译自《50 android hacks》

当创建复杂的布局的时候。有时候会发现加入了非常多的ViewGroup和View。随之而来的问题是View树的层次越来越深,应用也变的越来越慢,由于UI渲染是非常耗时的。

这时候就应该进行布局优化了。

这里介绍两种方式,分别为<include>标签和ViewStub类。


<include/>

使用<include/>是为了避免代码的反复。

设想一种情况。我们须要为app中的每一个视图都加入一个footer,这个footer是一个显示app名字的TextView。通常多个Activity相应多个XML布局文件,难道要把这个TextView复制到每一个XML中吗?假设TextView须要做改动,那么每一个XML布局文件都要进行改动,那简直是噩梦。

面向对象编程的当中一个思想就是代码的复用。那么怎么进行布局的复用呢?这时,<include/>就起作用了。

假设学过C语言,那么对#include应该不陌生,它是一个预编译指令,在程序编译成二进制文件之前。会把#include的内容复制到#include的位置。

Android中的<include/>也能够这么理解。就是把某些通用的xml代码复制到<include/>所在的地方。以一个Activity为例。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:text="@string/hello" /> <include layout="@layout/footer_with_layout_properties"/> </RelativeLayout>

footer_with_layout_properties.xml中就是一个简单的TextView,代码例如以下:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="30dp"
android:gravity="center_horizontal"
android:text="@string/footer_text" />

上述的代码中,我们使用了<include/>标签,达到了代码复用的目的。

可是。仍然存在一些疑惑。

footer_with_layout_properties.xml中使用了android:layout_alignParentBottom属性,这个属性之所以可行。是由于外层布局是RelativeLayout。

那么,假设外层布局换做LinearLayout又会如何呢?答案显而易见,这肯定是行不通的。

那么怎么办呢?我们能够把详细的属性写在<include/>标签里面。看以下的代码。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:text="@string/hello"/>
<include
layout="@layout/footer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="30dp"/>
</RelativeLayout>

我们直接在<include/>标签里面使用了android:layout_*属性。

注意:假设想要在<include/>标签中覆盖被包括布局所指定的不论什么android:layout_*属性,必须在<include/>标签中同一时候指定layout_width和layout_height属性。这可能是一个Android系统的一个bug吧。

ViewStub
在开发过程中。难免会遇到各种交互问题。比如显示或隐藏某个视图。假设想要一个视图仅仅在须要的时候显示,能够尝试使用ViewStub这个类。

先看一下ViewStub的官方介绍:

“ViewStub是一个不可视而且大小为0的视图,能够延迟到执行时填充布局资源。当ViewStub设置为Visible或调用inflate()之后。就会填充布局资源。ViewStub便会被填充的视图替代”。

如今已经清楚ViewStub能干什么了。那么看一个样例。一个布局中,存在一个MapView,仅仅有须要它的时候。才让它显示出来。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" > <Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:onClick="onShowMap"
android:text="@string/show_map" /> <ViewStub
android:id="@+id/map_stub"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:inflatedId="@+id/map_view"
android:layout="@layout/map" /> </RelativeLayout>

map.xml文件里包括一个MapView,仅仅有在必要的时候,才会让它显示出来。

<com.google.android.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:apiKey="my_api_key"
android:clickable="true" />

另外。inflatedId是ViewStub被设置成Visible或调用inflate()方法后返回的id,这个id就是被填充的View的id。在这个样例中,就是MapView的id。

接下来看看ViewStub是怎么使用的。

public class MainActivity extends MapActivity {

  private View mViewStub;

  @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mViewStub = findViewById(R.id.map_stub);
} public void onShowMap(View v) {
mViewStub.setVisibility(View.VISIBLE);
} @Override
protected boolean isRouteDisplayed() {
return false;
}
}

题外话

有的同学肯定会问,使用ViewStub和单纯地把View设置为View.GONE或View.VISIBLE有什么差别呢?不都是显示和隐藏吗,使用ViewStub反而更麻烦了。

确实是有差别的,会涉及到View树的渲染。内存消耗等。

至于有什么详细的差别,就请大家自己去Google吧。

俗话说。自己动手,丰衣足食嘛!

參考资料

http://code.google.com/p/android/issues/detail?id=2863

http://android-developers.blogspot.com.ar/2009/03/android-layout-tricks-3-optimize-with.html

http://developer.android.com/reference/android/view/ViewStub.html

【移动开发】布局优化利器&lt;include/&gt;和ViewStub的更多相关文章

  1. android开发布局优化之ViewStub

    使用ViewStub可以延迟加载一个布局文件,提高显示速率.刚开始接触到,记录下来. 关于viewstub的使用,我们可以在不同的布局中使用,比如可以根据设备的大小动态决定显示哪个界面. viewst ...

  2. 浅谈Android样式开发之布局优化

    引言 今天我们来谈一下Android中布局优化常用的一些手段.官方给出了3种优化方案,分别是</include>.</viewstub>.</merge>标签,下面 ...

  3. Android布局优化之include、merge、ViewStub的使用

    本文针对include.merge.ViewStub三个标签如何在布局复用.有效减少布局层级以及如何可以按需加载三个方面进行介绍的. 复用布局可以帮助我们创建一些可以重复使用的复杂布局.这种方式也意味 ...

  4. Android开发之布局优化

    1.抽象布局标签 (1) <include>标签 include标签经常使用于将布局中的公共部分提取出来供其它layout共用,以实现布局模块化.这在布局编写方便提供了大大的便利. 以下以 ...

  5. Android开发学习之路--性能优化之布局优化

      Android性能优化方面也有很多文章了,这里就做一个总结,从原理到方法,工具等做一个简单的了解,从而可以慢慢地改变编码风格,从而提高性能. 一.Android系统是如何处理UI组件的更新操作的 ...

  6. Android布局优化:include 、merge、ViewStub的详细总结

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 本篇博客主要是对上篇博客的补充Android性能优化之UI渲染性能优化, 没有什么新东西,觉得应该是都掌握的玩意,写出来也只是自己做个小小的总结. ...

  7. 布局优化之ViewStub、Include、merge使用分析

    布局技巧 在Android开发过程中,我们会遇到很多的问题,随着UI界面越来越多,布局的重复性.复杂度也随之增加,所幸的是,Android官方也给出了几个对布局进行优化的方法,下面根据自己的理解对官方 ...

  8. Android性能优化:布局优化 详细解析(含<include>、<ViewStub>、<merge>讲解 )

    1. 影响的性能 布局性能的好坏 主要影响 :Android应用中的页面显示速度 2. 如何影响性能 布局影响Android性能的实质:页面的测量 & 绘制时间 1个页面通过递归 完成测量 & ...

  9. 我的Android进阶之旅------>Android中的布局优化 include、merge 、ViewStub

    1.如何重用布局文件? 可以使用<include>标签引用其他的布局文件,并用android:id属性覆盖被引用布局文件中顶层节点的android:id属性值.代码如下: <!--引 ...

随机推荐

  1. POJ 1111(数字很吉利嘛) 简单BFS

    Image Perimeters Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8594 Accepted: 5145 Desc ...

  2. WPF TextBox 仅允许输入数字

    因为在 IValueConverter 实现中,当文本不能转换为目标类型时返回 DependencyProperty.UnsetValue ,Validation.GetHasError 返回 tru ...

  3. HTML+CSS(11)

    n  CSS背景属性 Background-color:背景色. Background-image:背景图片地址.如:background-image:url(images/bg.gif;) Back ...

  4. mysql 导入数据库时,报错1840的解决方法

    1.现象 在mysql用sql文件导入数据库时,提示ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @ ...

  5. python爬虫:爬取百度云盘资料,保存下载地址、链接标题、链接详情

    在网上看到的教程,但是我嫌弃那个教程写的乱(虽然最后显示我也没高明多少,哈哈),就随手写了一个 主要是嫌弃盘搜那些恶心的广告,这样直接下载下来,眼睛清爽多了. 用pyinstall 打包成EXE文件, ...

  6. python3设置打开文件的编码

    f = open(file_path,'r',encoding='utf8') 用起来很方便,不需要先读取再转码了.

  7. Docker 数据卷重复挂载测试

    没想到一年没写博客了,这中间都是记在自己的笔记本上,大部分网上都有,这个好像没有,所以发上来吧! 本文是测试Docker容器(相同目录/父子目录)同时挂载到宿主机(同目录/不同目录)时的情况,废话少说 ...

  8. 初识cocos creator的一些问题

    本文的cocos creator版本为v1.9.01.color赋值cc.Label组件并没有颜色相关的属性,但是Node有color的属性. //如果4个参数,在ios下有问题let rgb = [ ...

  9. 【转】虚拟化(四):vsphere高可用功能前提-共享存储搭建

    vsphere高级功能HA.DRS.FT等,都需要有共享存储环境,即多台esxi主机同时连接一个共享存储,这样在新建虚拟机时,可以指定把虚拟磁盘保存在共享存储上,便于虚拟机在各个主机之间“飘移”. 常 ...

  10. H3C交换机配置常用命令(转)

    1.配置文件相关命令 [Quidway]display current-configuration //显示当前生效的配置 [Quidway]display saved-configuration / ...