【移动开发】布局优化利器<include/>和ViewStub
本文翻译自《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
【移动开发】布局优化利器<include/>和ViewStub的更多相关文章
- android开发布局优化之ViewStub
使用ViewStub可以延迟加载一个布局文件,提高显示速率.刚开始接触到,记录下来. 关于viewstub的使用,我们可以在不同的布局中使用,比如可以根据设备的大小动态决定显示哪个界面. viewst ...
- 浅谈Android样式开发之布局优化
引言 今天我们来谈一下Android中布局优化常用的一些手段.官方给出了3种优化方案,分别是</include>.</viewstub>.</merge>标签,下面 ...
- Android布局优化之include、merge、ViewStub的使用
本文针对include.merge.ViewStub三个标签如何在布局复用.有效减少布局层级以及如何可以按需加载三个方面进行介绍的. 复用布局可以帮助我们创建一些可以重复使用的复杂布局.这种方式也意味 ...
- Android开发之布局优化
1.抽象布局标签 (1) <include>标签 include标签经常使用于将布局中的公共部分提取出来供其它layout共用,以实现布局模块化.这在布局编写方便提供了大大的便利. 以下以 ...
- Android开发学习之路--性能优化之布局优化
Android性能优化方面也有很多文章了,这里就做一个总结,从原理到方法,工具等做一个简单的了解,从而可以慢慢地改变编码风格,从而提高性能. 一.Android系统是如何处理UI组件的更新操作的 ...
- Android布局优化:include 、merge、ViewStub的详细总结
版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 本篇博客主要是对上篇博客的补充Android性能优化之UI渲染性能优化, 没有什么新东西,觉得应该是都掌握的玩意,写出来也只是自己做个小小的总结. ...
- 布局优化之ViewStub、Include、merge使用分析
布局技巧 在Android开发过程中,我们会遇到很多的问题,随着UI界面越来越多,布局的重复性.复杂度也随之增加,所幸的是,Android官方也给出了几个对布局进行优化的方法,下面根据自己的理解对官方 ...
- Android性能优化:布局优化 详细解析(含<include>、<ViewStub>、<merge>讲解 )
1. 影响的性能 布局性能的好坏 主要影响 :Android应用中的页面显示速度 2. 如何影响性能 布局影响Android性能的实质:页面的测量 & 绘制时间 1个页面通过递归 完成测量 & ...
- 我的Android进阶之旅------>Android中的布局优化 include、merge 、ViewStub
1.如何重用布局文件? 可以使用<include>标签引用其他的布局文件,并用android:id属性覆盖被引用布局文件中顶层节点的android:id属性值.代码如下: <!--引 ...
随机推荐
- B - Sleuth
Problem description Vasya plays the sleuth with his friends. The rules of the game are as follows: t ...
- struts2框架搭建(一)
struts2是一个基于mvc的web应用框架.struts2本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器层(Controller)来建立模型与视图的数据交互. str ...
- EntityFramewok 插入Mysql数据库 中文产生乱码解决
首先Mysql表,建表的时候,有没有选择UTF8,如果是默认的编码latin1,就会产生乱码 这里修改后,还是乱码,那就要检查发生乱码的列是不是UTF8格式 然后修改App.Config或者Web.C ...
- matplotlib之pyplot 学习示例
现在通过numpy和matplotlib.pyplot 在Python上实现科学计算和绘图,而且和matlab极为相像(效率差点,关键是方便简单) 这里有大量plots代码例子. 1. 简单的绘图( ...
- android中复制图片
activity_main.xml中的配置 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/androi ...
- (转载) ORA-12537:TNS连接已关闭
今天在远程客户端配置EBS数据库连接的时候发生“ORA-12537:TNS连接已关闭”的错误.进入服务器运行如下命令:$tnsping VIS 这里VIS如果定义服务名,可以写成 $ tnsping ...
- Python 遍历目录
代码: 1.递归使用遍历目录 import os def scanfile(path): filelist = os.listdir(path) allfile = [] for filename i ...
- Visual Basic for Application
Private Sub Worksheet_SelectionChange(ByVal Target As Range) 'The note of Visual Basic for Applicati ...
- 07--c++类的构造函数详解
c++类的构造函数详解 c++构造函数的知识在各种c++教材上已有介绍,不过初学者往往不太注意观察和总结其中各种构造函数的特点和用法,故在此我根据自己的c++编程经验总结了一下c++中各种构造函数的特 ...
- 【剑指Offer】38、二叉树的深度
题目描述: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 解题思路: 本题相对比较简单.根据二叉树深度的定义 ...