在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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()后会都传给相应的布局。

ViewStub用法相关推荐

  1. Android知识点及资料汇总(不断更新中)

    /// //版本:0.1 //主要内容:根据思维导图的知识点,对之前收藏夹的内容进行分类. /// 之前转载过一篇题目为<一张思维导图,告诉你Android新手如何快速入门>的文章,这篇文 ...

  2. Android系统学习(37)---Android知识点及资料汇总

    Android知识点及资料汇总 废话不多说,直接上总结: Android入门方法和经验之谈 如何自学 Android 编程? 如何零基础学习安卓开发? 我是如何自学,资料分享 一张Android学习的 ...

  3. [转载]Android Layout标签之-viewStub,requestFocus,merge,include

    定义Android Layout(XML)时,有四个比较特别的标签是非常重要的,其中有三个是与资源复用有关,分别是<viewStub/>, <requestFocus />, ...

  4. android support v4 viewstub,Android 控件ViewStub

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

  5. Android Layout标签之-viewStub,requestFocus,merge,include

    定义Android Layout(XML)时,有四个比较特别的标签是非常重要的,其中有三个是与资源复用有关,分别是<viewStub/>, <requestFocus />, ...

  6. Android列表用法之二:实战ListView高级用法

    在我们的项目中,并不是所有列表都是简单的使用.类似于新闻列表.QQ聊天列表等,具有图文并排的列表,每个item都有它不同的布局类型,都有其不同的实现方式.这类复杂的列表表现形式,在各类知名应用当中,不 ...

  7. 深入分析 ViewStub 原理

    前言 最近在面试的时候被面试官问到ViewStub内部是如何使用占位的时候,我是一脸懵逼,说实话我之前对UI上的一些控件内部的代码看的非常少,所以一时答不上来,这个东西其实并不说有多难,而是我们平时在 ...

  8. c语言中external,static关键字用法

    static用法: 在C中,static主要定义全局静态变量.定义局部静态变量.定义静态函数. 1.定义全局静态变量:在全局变量前面加上关键字static,该全局变量变成了全局静态变量.全局静态变量有 ...

  9. Pandas_transform的用法

    先来看一个实例问题. 如下销售数据中展现了三笔订单,每笔订单买了多种商品,求每种商品销售额占该笔订单总金额的比例.例如第一条数据的最终结果为:235.83 / (235.83+232.32+107.9 ...

  10. Python中yield和yield from的用法

    yield 后面接的是 future 对象 调用方 委托生成器 yield from 直接给出循环后的结果 yield from 委托者和子生成器直接通信 yield from 直接处理stopIte ...

最新文章

  1. 根据各工序时间画aoe网_曲靖被动防护网RXI150被动网厂家
  2. leetcode two sum python_LeetCode专题-Python实现之第1题:Two Sum
  3. 消灭星星网页版java代码,javascript实现消灭星星小游戏简单版
  4. subList?? subString???
  5. python设置默认密码_使用Python生成随机密码的示例分享
  6. magento 增加一个layout template
  7. 多线程环境下,HashMap 为什么会出现死循环?
  8. 架构之每天数十亿次请求的web应用经验分享
  9. python-django rest framework框架之渲染器
  10. 面试题——关于文本加密
  11. 磁力mysql搜索_求一份磁力链接搜索网站的源码,最好能来个大神讲一下这个搜索的原理...
  12. 动态数据可视化图表制作
  13. 我的世界电脑服务器怎么显示键盘,我的世界电脑版操作按键
  14. Ka的分治|归并排序,注释详尽
  15. ❤️数据可视化❤️:基于Echarts + GeoJson实现的地图视觉映射散点(气泡)组件【15】 - 江西省
  16. c++语言程序设计教程与实验实验报告,C++程序设计课程设计实验报告—网络五子棋...
  17. 【BZOJ3398】牡牛和牝牛
  18. 【精】2021年shopee值不值得做?吐槽shopee的坑和避坑指南
  19. lxml库的基本使用
  20. 【Mark】概率论与数理统计

热门文章

  1. win10简单方法安装杜比v4音效!win10 1909适用!
  2. 线性规划问题的模型建立与求解
  3. 【有图有真相】全国软考高级三连冠感悟
  4. 计算机一级考试搜题app,计算机一级考试题库答案,哪个搜题软件能找到?
  5. 找不到任何设备驱动程序.请确保安装介质_win10安装完全手册,详细全面,新手必备...
  6. 珠海华润银行网银密码控件
  7. (二十三)美萍酒店管理系统:系统维护_系统设置_商品设置_添加类别、添加商品
  8. android SD卡文件夹
  9. 谷歌、火狐浏览器扩展开发
  10. 2012年3月份第2周51Aspx源码发布详情