转自http://blog.csdn.net/hitlion2008/article/details/6737537

在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局。那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在代码中动态的更改它的可见性。这样的做法的优点是逻辑简单而且控制起来比较灵活。但是它的缺点就是,耗费资源。虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。也就是说,会耗费内存等资源。

推荐的做法是使用android.view.ViewStub,ViewStub 是一个轻量级的View,它一个看不见的,不占布局位置,占用资源非常小的控件。可以为ViewStub指定一个布局,在Inflate布局的时候,只有 ViewStub会被初始化,然后当ViewStub被设置为可见的时候,或是调用了ViewStub.inflate()的时候,ViewStub所向 的布局就会被Inflate和实例化,然后ViewStub的布局属性都会传给它所指向的布局。这样,就可以使用ViewStub来方便的在运行时,要还 是不要显示某个布局。

但ViewStub也不是万能的,下面总结下ViewStub能做的事儿和什么时候该用ViewStub,什么时候该用可见性的控制。

首先来说说ViewStub的一些特点:

1. ViewStub只能Inflate一次,之后ViewStub对象会被置为空。按句话说,某个被ViewStub指定的布局被Inflate后,就不会够再通过ViewStub来控制它了。

2. ViewStub只能用来Inflate一个布局文件,而不是某个具体的View,当然也可以把View写在某个布局文件中。

基于以上的特点,那么可以考虑使用ViewStub的情况有:

1. 在程序的运行期间,某个布局在Inflate后,就不会有变化,除非重新启动。

因为ViewStub只能Inflate一次,之后会被置空,所以无法指望后面接着使用ViewStub来控制布局。所以当需要在运行时不止一次的显示和
隐藏某个布局,那么ViewStub是做不到的。这时就只能使用View的可见性来控制了。

2. 想要控制显示与隐藏的是一个布局文件,而非某个View。

因为设置给ViewStub的只能是某个布局文件的Id,所以无法让它来控制某个View。

所以,如果想要控制某个View(如Button或TextView)的显示与隐藏,或者想要在运行时不断的显示与隐藏某个布局或View,只能使用View的可见性来控制。

下面来看一个实例

在这个例子中,要显示二种不同的布局,一个是用TextView显示一段文字,另一个则是用ImageView显示一个图片。这二个是在onCreate()时决定是显示哪一个,这里就是应用ViewStub的最佳地点。

先来看看布局,一个是主布局,里面只定义二个ViewStub,一个用来控制TextView一个用来控制ImageView,另外就是一个是为显示文字的做的TextView布局,一个是为ImageView而做的布局:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="fill_parent"
  6. android:layout_height="fill_parent"
  7. android:gravity="center_horizontal">
  8. <ViewStub
  9. android:id="@+id/viewstub_demo_text"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"
  12. android:layout_marginLeft="5dip"
  13. android:layout_marginRight="5dip"
  14. android:layout_marginTop="10dip"
  15. android:layout="@layout/viewstub_demo_text_layout"/>
  16. <ViewStub
  17. android:id="@+id/viewstub_demo_image"
  18. android:layout_width="wrap_content"
  19. android:layout_height="wrap_content"
  20. android:layout_marginLeft="5dip"
  21. android:layout_marginRight="5dip"
  22. android:layout="@layout/viewstub_demo_image_layout"/>
  23. </LinearLayout>

为TextView的布局:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="wrap_content"
  6. android:layout_height="wrap_content">
  7. <TextView
  8. android:id="@+id/viewstub_demo_textview"
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content"
  11. android:background="#aa664411"
  12. android:textSize="16sp"/>
  13. </LinearLayout>

为ImageView的布局:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="wrap_content"
  6. android:layout_height="wrap_content">
  7. <ImageView
  8. android:id="@+id/viewstub_demo_imageview"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"/>
  11. </LinearLayout>

下面来看代码,决定来显示哪一个,只需要找到相应的ViewStub然后调用其infalte()就可以获得相应想要的布局:

  1. package com.effective;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.view.ViewStub;
  5. import android.widget.ImageView;
  6. import android.widget.TextView;
  7. public class ViewStubDemoActivity extends Activity {
  8. @Override
  9. public void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. setContentView(R.layout.viewstub_demo_activity);
  12. if ((((int) (Math.random() * 100)) & 0x01) == 0) {
  13. // to show text
  14. // all you have to do is inflate the ViewStub for textview
  15. ViewStub stub = (ViewStub) findViewById(R.id.viewstub_demo_text);
  16. stub.inflate();
  17. TextView text = (TextView) findViewById(R.id.viewstub_demo_textview);
  18. text.setText("The tree of liberty must be refreshed from time to time" +
  19. " with the blood of patroits and tyrants! Freedom is nothing but " +
  20. "a chance to be better!");
  21. } else {
  22. // to show image
  23. // all you have to do is inflate the ViewStub for imageview
  24. ViewStub stub = (ViewStub) findViewById(R.id.viewstub_demo_image);
  25. stub.inflate();
  26. ImageView image = (ImageView) findViewById(R.id.viewstub_demo_imageview);
  27. image.setImageResource(R.drawable.happy_running_dog);
  28. }
  29. }
  30. }

运行结果:

使用的时候的注意事项:

1.
某些布局属性要加在ViewStub而不是实际的布局上面,才会起作用,比如上面用的android:layout_margin*系列属性,如果加在
TextView上面,则不会起作用,需要放在它的ViewStub上面才会起作用。而ViewStub的属性在inflate()后会都传给相应的布
局。

虽然很简单,但是感觉实际应用中比较少见

android之ViewStub的使用的更多相关文章

  1. Android中ViewStub组件使用

    1. 概述: ViewStub组件和<include>标签的作用类似,主要是为了提高布局的重用性,及布局的模块化.它们之间最大的差别是,ViewStub中的布局不会随着它所在布局的渲染而渲 ...

  2. android 之ViewStub

    在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局.那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在 ...

  3. Android实战技巧:ViewStub的应用

    在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局.那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在 ...

  4. Android 高级UI设计笔记16:ViewStub的应用

    1. ViewStub 在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局. 那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为 ...

  5. 【Android 界面效果37】ViewStub的应用

    在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局.那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在 ...

  6. Android性能优化之ViewStub

    http://www.cnblogs.com/lwbqqyumidi/p/4047108.html ViewStub是Android布局优化中一个很不错的标签/控件,直接继承自View.虽然Andro ...

  7. 【转】Android API 中文(14) —— ViewStub

    用一个XML源填充view.inflate(上下文对象,资源文件Id,父窗口组一般为null): 原文网址:http://www.cnblogs.com/over140/archive/2010/10 ...

  8. Android 性能优化 三 布局优化ViewStub标签的使用

    小黑与小白的故事,通过虚拟这两个人物进行一问一答的形式来共同学习ViewStub的使用 小白:Hi,小黑,ViewStub是什么?听说能够用来进行布局优化. 小黑:ViewStub 是一个隐藏的,不占 ...

  9. Android性能优化:ViewStub

    在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局.那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在 ...

随机推荐

  1. 一个快速、高效的Levenshtein算法实现——代码实现

    在网上看到一篇博客讲解Levenshtein的计算,大部分内容都挺好的,只是在一些细节上不够好,看了很长时间才明白.我对其中的算法描述做了一个简单的修改.原文的链接是:一个快速.高效的Levensht ...

  2. EFI安装Win7

    安装系统之前电脑里最好没有其他系统,安装过程中电脑需重启多次,其他系统会引导电脑开机,无法完成WIN7安装. 一.制作安装分区 1.首先在移动硬盘(U盘)准备一个FAT32分区 一定要FAT32分区, ...

  3. 关于指针要注意的地方还有尝试在codeblocks上建立项目

    1.字符串: char a[]="house"; char *b="house"; a[2]='r';可以   b[2]='r'不可以,因为这个指针变量指的是字 ...

  4. namenode无法启动

    查看日志错误信息关键语句: There appears to be a gap in the edit log.  We expected txid 44353, but got txid 原因: n ...

  5. 基于TCP协议的网络编程

    TCP通信协议是一种可靠的传输层协议,它在通信的两端各建立一个Socket,从而在通信的两端之间形成虚拟网络链路.一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信.Java使用Socke ...

  6. javascript中的面向对象—— 学习1

    面向对象:Object Oriented(OO) 一切事物皆对象,通过面向对象的方式,将显示世界的事物抽象成对象,将显示世界中的关系抽象成类.继承,帮助人们实现对显示世界的抽象与数字建模:--百科 一 ...

  7. sf中schedule设定

    博客园龄有两年多了,看了一下我发的文章数和最后发布的日期,不禁的心头一怔,已经有一年都没有写更新博客了.突然想起一个句子好像说的是我:间歇性踌躇满志,持续性懒惰等死.最近也看到一位好朋友的qq个性签名 ...

  8. Android5.1源码Xposed框架编译

    介绍 Xposed框架是一款可以在不修改APK的情况下影响程序运行(修改系统)的框架服务,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作 . 对于Android5.1系统,官方提供 ...

  9. Oracle截取某字段前后字符串

    创建测试表及数据 1 2 3 4 5 6 7 8 9 create table test (name varchar2(10));   insert into test values ('2-15') ...

  10. OBIEE 12C

    OBIEE 12C安装配置 oracle官网下载BIEE12C 在虚拟机上安装 linux 在SQLPLUS启动和停止Oracle数据库 重启oracle数据库 cmd->1.lsnrctl s ...