本文翻译自《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. struts2标签(五)

    标签体系结构 jsp出现目的是为了取代servlet,结果逻辑代码,数据库代码都放到了jsp页面中. 为了解决jsp中代码过多的问题,struts2标签分为普通标签和UI标签. 使用struts2标签 ...

  2. Redis学习笔记(五)- 数据类型之set类型

    Redis 的set是string类型的无序集合.set元素最大可以包含(2的32次方-1)个元素.set的是通过hash table实现的,所以添加,删除,查找的复杂度都是O(1).hash tab ...

  3. 关于jquery的clone()和javascript的cloneNode()

    区别: jquery的clone( ),如果是true就是深克隆,把事件都会克隆过去:如果是false,则仅仅克隆的是结构: javascript的cloneNode( ),如果是true,会将子节点 ...

  4. 上传文件到linux系统方法

    linux,windows filezilla 方法/步骤     下载 Filezilla client工具,此客户端为免费软件,下载完成后安装,安装一路下一步在这里就不过多阐述了,下载地址 htt ...

  5. angular js shopping

    <!DOCTYPE html>   <html lang="en">   <head>   <meta charset="UTF ...

  6. YOLO (You Only Look Once)

    YOLO (You Only Look Once) dl  cnn  object detection  一.YOLO YOLO是一个实时的目标检测系统.最新的V2版本在Titan X 上可以每秒处理 ...

  7. mysql 5.6 中 explicit_defaults_for_timestamp参数

    mysql 5.6 中 explicit_defaults_for_timestamp参数 一: 官方文档中关于explicit_defaults_for_timestamp参数说明如下: expli ...

  8. vue-awesome-swiper组件的使用

    一.轮播图组件是这样安装的 npm i --save-dev vue-awesome-swiper main.js里面 import 'swiper/dist/css/swiper.css' impo ...

  9. Tomcat Eclipse Debug出现异常

    1.可能是java类没有及时更新成class文件2.本地程序没有同步到Tommcat服务器里面3.Servlet类里面加了版本号private static final long serialVers ...

  10. BZOJ 4259: 残缺的字符串 FFT_多项式

    Code: #include<bits/stdc++.h> #define maxn 1200000 using namespace std; void setIO(string s) { ...