小黑与小白的故事,通过虚拟这两个人物进行一问一答的形式来共同学习ViewStub的使用

小白:Hi,小黑,ViewStub是什么?听说能够用来进行布局优化。

小黑:ViewStub 是一个隐藏的,不占用内存空间的视图对象。它能够在执行时延迟载入布局资源文件。(很多其它具体的API等信息能够查看官方文档ViewStub),计算机行业一向是实践里面出真知,以下用一个样例演示下效果。


小黑:说说概念仅仅是为了概括性的了解下。还是用个实例来演示下。先来创建一个Activity中使用的布局文件,文件名称是:activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" > <Button
android:id="@+id/show_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示"/> <ViewStub
android:id="@+id/viewstub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout="@layout/sub_layout"
/> <Button
android:id="@+id/hide_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="隐藏"/> </LinearLayout>

小白:“显示”、“隐藏”字符串没有放入values/string.xml。控件的id也没有一定的命名规则的乱起。


小黑:。。。。。。“你是猴子请来的救兵吗?”。一切从简好吧。注意上面的ViewStub的使用方法。当中android:layout="@layout/sub_layout"引入一个新的布局。sub_layout.xml代码例如以下:
<TextView  xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ViewStub中包括的TextVeiw"/>

小白:如今有两个布局文件了,一个是Activity setContentView须要的activity_main.xml,一个是当中引入的sub_layout

小黑:以下是一个MainActivity.java。加入些点击事件
package com.example.viewstub;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewStub;
import android.view.View.OnClickListener; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); final ViewStub viewStub = (ViewStub) findViewById(R.id.viewstub); View showButton = findViewById(R.id.show_button);
showButton.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
viewStub.inflate();
}
}); View hideButton = findViewById(R.id.hide_button);
hideButton.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
viewStub.setVisibility(View.GONE);
}
});
}
}

小黑:以下是代码执行后,默认并没有点击显示button的情况下。使用“DDMS -> Dump View Hierarchy for UI Automator”工具的截图



小白:我发现activity_main.xml布局文件在“显示”,“隐藏”两个button之间有一个<ViewStub>而在上面的截图中并没有。说明ViewStub在初始化载入时并不会加入到视图树上(Android UI Tree)。

我也使用“Hierarchy View”工具的截图例如以下:






小黑:对,这是ViewStub能够进行布局优化的地方“懒载入视图”,初始化时系统不会初始化ViewStub引用的视图。

再来看下接着看下点击“显示”button后的截图。





小黑:ViewStub使用流程是 1. 布局中加入ViewStub (XML加入、代码中加入) 2. inflate显示 3. setVisibility隐藏。


小白:通过在代码中viewStub.inflate(); ViewStub引用的布局显示出来了。只是,这不就是动态的加入视图吗?与View.setVisibility(View.GONE);有啥差别?

小黑:ViewStub是一个没有尺寸大小而且不会在布局中嵌套或渲染不论什么东西的轻量级的视图。因此在视图层次展现或隐藏它的代价很小。当ViewStub可见,或者调用 inflate()函数时,才会载入这个布局资源文件。

该ViewStub在载入视图时在父容器中替换它本身。

因此,ViewStub会一直存在于视图中。直到调用setVisibility(int) 或者inflate()为止。ViewStub的布局參数会随着载入的视图数一同被加入到ViewStub父容器。相同,你也能够通过使用inflatedId属性来定义或重命名要载入的视图对象的Id值。

    View.setVisibility(View.GONE); 方式在初始化时就会加入到视图树上(Android UI Tree),而使用ViewStub在初始化时不会加入。

小白:使用ViewStub有啥须要注意的吗?
小黑:1. 在要渲染的布局中并不支持<merge/>标签。

2. ViewStub.infalte方法不能调用两次。否者会出现下面异常:


java.lang.IllegalStateException: ViewStub must have a non-null ViewGroup viewParent
at android.view.ViewStub.inflate(ViewStub.java:287)
at com.example.viewstub.MainActivity$1.onClick(MainActivity.java:23)
at android.view.View.performClick(View.java:4475)
at android.view.View$PerformClick.run(View.java:18786)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
at dalvik.system.NativeStart.main(Native Method)

小白:在网上看的资料说是ViewStub的一个缺点是引入的布局不能使单独的视图,而必须是一个布局才行,是这样吗?
小黑:这样的观点是错误的。在样例sub_layout.xml 中仅有一个TextView视图。

小白:为什么ViewStub能够作为一个布局标签使用?
小黑:你能够查看一下ViewStub的源代码。public
final class ViewStub extends View。 ViewStub本身就是一个View 子类。


小白:我有几个问题:
1. ViewStub加入的视图能够动态删除吗?
2. 不能第二次inflate为什么?
3. 尽管第二次不能直接inflate,能够直接删除,代码中加入视图吗?
4. 除了调用inflate方法还能通过其它方式显示出来吗?(找到id 设置visible)

小黑:偶不知道啊。



补充:ViewStub显示有两种办法。上面介绍的是使用inflate方法,还能够直接在ViewStub.setVisibiltity(View.Visible)

异常情况:
    <ViewStub
android:id= "@+id/view_stub_text"
android:layout_width= "wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:layout_width= "wrap_content"
android:layout_height="wrap_content"
android:text="love_world_"
/>
</ViewStub >

出现下面异常:

java.lang.ClassCastException: android.view.ViewStub cannot be cast to android.view.ViewGroup

使用场景:
ListView ItemView
     个人评估是否有必要
     Gone是否也已经优化?


參考资料
ViewStub - 官方文档
Loading Views On Demand - 官方教程


很多其它优化相关的文章详见:《Android 基础学习文章汇总》 第三部分 性能优化


2014-11-12  加入异常与使用场景

Android 性能优化 三 布局优化ViewStub标签的使用的更多相关文章

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

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

  2. Android性能优化之布局优化

    最新最准确内容建议直接访问原文:Android性能优化之布局优化 本文为Android性能优化的第二篇——布局优化,主要介绍使用抽象布局标签(include, viewstub, merge).去除不 ...

  3. 【转】Android性能优化之布局优化篇

     转自:http://blog.csdn.net/feiduclear_up/article/details/46670433 Android性能优化之布局优化篇 分类: andorid 开发2015 ...

  4. Android 性能优化 四 布局优化merge标签的使用

    小白:之前分享了ViewStub标签的使用,Android还有其他优化布局的方式吗? 小黑:<merge />标签用于减少View树的层次来优化Android的布局.先来用个例子演示一下: ...

  5. Android Studido下的应用性能优化总结--布局优化

    前言:一个应用的成功=产品设计*性能 ,再此我们不讨论一个应用的设计,那交给我们可爱又可恨的产品经理和UI设计师来决定!所以这里分步骤讨论如何提升一个应用的性能,这里先探讨布局优化问题. 布局优化 避 ...

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

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

  7. Android最佳性能实践(四)——布局优化技巧

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43376527 在前面几篇文章其中.我们学习了怎样通过合理管理内存,以及高性能编码技 ...

  8. android 优化之布局优化

    布局优化的思路很简单,尽量减少布局文件的层级,看过系统源码的都知道,Android view绘制都是逐层绘制的,所以布局的层级少了,decodeview的时候绘制工作自然就少了. 那么如何进行布局的优 ...

  9. Android 卡顿优化 4 布局优化实际技巧

    今天分享一些layout布局书写中的一些技巧,希望看过之后你也一样可以写出性价比高的布局.我个人的目标是用最少的View写出一样效果的布局.因为我相信View的数量减少伴随着的就是层级的减少.从而达到 ...

随机推荐

  1. Linux各个发行版本的介绍, 以及VirtualBox+CentOS的安装步骤

    Linux和Unix系统有哪些主要的发行版本 Unix: (非开源传统商业操作系统) IBM AIX, HP HP-UX, Sun Solaris,等 各家硬件厂商的发行版本, 往往是和自家的硬件设备 ...

  2. 星际SC 地图 Big Game Fort 要塞之战 修正了 BIG GAME 地图的平衡性

    星际SC 地图 Big Game Fort 要塞之战 修正了 BIG GAME 地图的平衡性 也适合BIG 1V1 对战 此版本目前不开放1打1造功能

  3. 基于KVM建立虚拟机的步骤及总结说明

    1.前言 目前正在涉足云计算IaaS工作,虚拟化是IaaS的重要部分,因此这段时间对各个虚拟机化技术和工具进行研究,研究的目的不仅仅是为了会使用这个工具,而是通过研究了解技术的实现机制和原理,即知其然 ...

  4. 教你看懂C++类库函数定义之二---STDMETHOD介绍

    一切从一个C++ 类库头文件开始,现在在做一个C++的项目,期间用到一个开源的界面库DUILib(类似MFC),这个东西还不错能很容易的写出漂亮的界面,比如QQ的界面,可以去下载下来研究研究,地址:h ...

  5. 动态子类化CComboBox以得到子控件EDIT及LISTBOX

    动态子类化CComboBox以得到子控件EDIT及LISTBOX Joise.LI写于2004-4-6 ComboBox是比较常用的一个控件,有三种样式:CBS_SIMPLE(简单),CBS_DROP ...

  6. c++ - fcgio.cpp:50: error: 'EOF' was not declared in this scope - Stack Overflow

    c++ - fcgio.cpp:50: error: 'EOF' was not declared in this scope - Stack Overflow fcgio.cpp:50: error ...

  7. java的表达式

    Java是面向表达式的语言,Java中一个简单表达式可以是下面任意一种: ● 常量:7.false.● 单引号括起来的字符字面常量:'A'.'3'.● 双引号括起来的字符串字面常量:"foo ...

  8. Windows 10 安装

    下载了 Windows 10 的 ISO 文件:WindowsTechnicalPreview-x64-ZH-CN.iso,在 VMWare 10 上进行了安装. 安装时没有 Windows 10   ...

  9. Mysql++详解

    MySQL++数据库操作(1).mysqlpp::Connection con(false); //定义了mysql连接对象: (2).con.set_option(new mysqlpp::SetC ...

  10. Dos关闭进程命令

    netstat -ao 查找占用端口的进程 taskkikk /pid 端口pid  /f