本文翻译自《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. [转]Oracle 存储过程语法

    转自:http://www.cnblogs.com/chuncn/archive/2009/04/29/1381282.html 存储过程 1  CREATE OR REPLACE PROCEDURE ...

  2. AFN请求后台返回数据为NSInlineData类型的处理

    在利用AFN进行数据解析时出现返回数据为 <7b227374 61747573 223a302c 226d6573 73616765 223a22e6 82a8e79a 84e6898b e69 ...

  3. Asp.net MVC4 Step by Step (3)-数据验证

    ASP.NET MVC把数据验证集成到了请求处理过程中,控制器操作可以通过查询ModelState 来检查请求是否有效, 下面判断了ModelState的有效性后进行“保存或返回”操作.   [Htt ...

  4. C# Socket通讯 本机多网卡,指定网卡通讯

    IPAddress ip = IPAddress.Parse("192.168.0.188"); IPAddress IPLocal = IPAddress.Parse(" ...

  5. SLAM: Ubuntu14.04_Kylin安装ROS-Indigo

    参考连接:ROS-Indigo版在Ubuntu上的安装第一步: 软件源配置 1. 增加下载源(增加ubuntu版的ros数据仓库,即下载源)(通用指令适合任何版本的ros) sudo sh -c 'e ...

  6. AI 的会议总结(by南大周志华)

    原文链接:http://blog.csdn.net/akipeng/article/details/6533897 这个列的更详细:http://www.cvchina.info/2010/08/31 ...

  7. CDR中国元素圆形花纹矢量图制作流程

    在论坛中看到这样一个问题,想要使用CorelDRAW矢量绘图工具做出下图所示的中国元素圆形花纹矢量图,小编潜心研究一下,最终有了绘制方法,今天给大家分享下. 步骤一:画同心圆,先画出10个,这个是根据 ...

  8. 腾讯模板引擎template

    template.js是一款JavaScript模板引擎,用来渲染页面的. 原理:提前将Html代码放进编写模板  script id="tpl" type="text/ ...

  9. rabbitmq-3.5.1-安裝

    系统版本:CentOS 6.5RabbitMQ-Server:3.5.1一.安装erlang1.安装准备,下载安装文件 wget https://packages.erlang-solutions.c ...

  10. Django基础(二)

    Django基础(二) http://www.cnblogs.com/wupeiqi/articles/4508271.html