原帖地址: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而做的布局:

[html] view plaincopyprint?
  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的布局:

[html] view plaincopyprint?
  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的布局:

[html] view plaincopyprint?
  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()就可以获得相应想要的布局:

[java] view plaincopyprint?
  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. }

运行结果:

下面是原帖的回复中的建议:

[java] view plaincopyprint?
  1. if ((((int) (Math.random() * 100)) & 0x01) == 0) {
  2. ViewStub stub = (ViewStub) findViewById(R.id.viewstub_demo_text);
  3. View view = stub.inflate();
  4. TextView text = (TextView) view.findViewById(R.id.viewstub_demo_textview);
  5. text.setText("The tree of liberty must be refreshed from time to time" +
  6. " with the blood of patroits and tyrants! Freedom is nothing but " +
  7. "a chance to be better!");
  8. } else {
  9. ViewStub stub = (ViewStub) findViewById(R.id.viewstub_demo_image);
  10. View view = stub.inflate();
  11. ImageView image = (ImageView) view.findViewById(R.id.viewstub_demo_imageview);
  12. image.setImageResource(R.drawable.happy_running_dog);
  13. }

ViewStub.inflate返回的就是layout的根节点对象,通过根节点的引用去查找其中的子view效率会稍微有所提升(子view较多的情况下)

使用的时候的注意事项:

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

Android ViewStub的应用相关推荐

  1. Android ViewStub

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

  2. Android ViewStub控件

    前言 使用ViewStub可以实现界面的延迟加载. 1. ViewStub简单应用 布局文件,layout为加载View,inflatedId为加载后View的id. <ViewStubandr ...

  3. android support v4 viewstub,Android 控件ViewStub

    Android ViewStub 01. 简介 A ViewStub is an invisible, zero-sized View that can be used to lazily infla ...

  4. android开发相关资料整理【2011-10-29】

    外文译本--andbook Android开发基础书籍 Android CheckBox的isChecked属性 方法的反射 Android BluetoothClass.Device Android ...

  5. 2020 Android 面试重难点(万字篇),字节,移动端app开发框架

    跨进程间通信(IPC):四大组件之间通过Intent互相跳转,Android实现IPC的方式是binder机制. [android中的跨进程通信的实现(一)--远程调用过程和aidl] [Androi ...

  6. Android布局优化之include、merge、ViewStub

    include:引入重复使用的相同布局 merge:减少include布局的层级,将子元素直接添加到merge标签的parent中 ViewStub:其实就是一个宽高都为0的一个View,它默认是不可 ...

  7. Android抽象布局——include、merge 、ViewStub

    在布局优化中,Androi的官方提到了这三种布局<include />.<merge />.<ViewStub />,并介绍了这三种布局各有的优势,下面也是简单说一 ...

  8. Android中使用ViewStub提高布局性能

    2019独角兽企业重金招聘Python工程师标准>>> 注,关于Stub的解释:在Java中,桩(stub)是指用来代替关联代码或者未实现代码的代码. ViewStub使用场景 如上 ...

  9. Android性能优化之一:ViewStub

    Android性能优化之一:ViewStub 转载于:https://www.cnblogs.com/zhujiabin/p/5223196.html

最新文章

  1. GDAL中GDALDataset::RasterIO分块读取的实现
  2. webpack4配置详解
  3. C/C++中.和-的用法区别
  4. java中getClass().getResourceAsStream()与getClass().getClassLoader().getResourceAsStream()的区别
  5. IDA*-洛谷P1379 八数码难题
  6. linux sql server硬件要求,SQL Server On Linux(20)—— SQL Server On Linux性能(6)——针对性能的配置(Linux层面)...
  7. Linux按照CPU、内存、磁盘IO、网络性能监测
  8. python求素数算法_Python程序最多可计算n个质数(使用不同算法)
  9. 《Kotlin进化之路》之【第二章:揭开Kotlin的基础面纱】(二)
  10. 企业发展如何启动云的力量
  11. js 刷新,返回上一步,前进,后退,
  12. Kali Linux 软件源和软件更新(留着自己看)
  13. 谈心-弱之胜强,柔之胜刚
  14. 麻将判断胡牌 java_麻将胡牌逻辑 java
  15. java 生成数字_Java随机生成数字的方法
  16. 安装office时总得到“安装程序包的语言不受系统支持”的提示解决方法
  17. osm地图数据 mysql_一种OSM地图数据中路网交叉口节点自动合并方法与流程
  18. 关于linux网络编程的项目,linux网络编程入门
  19. 计算机网络实验--Cisco Packet Tracer 实验
  20. [日常] [Python] 批量将某个文件夹下的.ppt/.pptx/.pptm转换为.pdf文件,并且将其移入/ppt文件夹中

热门文章

  1. java 登录数据前端加密+后台验证RSA
  2. Linux下的进程相关编程
  3. TCP/IP学习笔记(七)四次挥手
  4. 记录docker常用的command
  5. Mac查看Android动态库依赖
  6. 搜索旋转排序数组—leetcode31
  7. LeetCode每日一题 844. 比较含退格的字符串
  8. Problem - 4828 Grids
  9. ubuntu18下安装微信
  10. Linux添加用户(user)到用户组(group)