在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个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?

<?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout  
      xmlns:android="http://schemas.android.com/apk/res/android"  
      android:orientation="vertical"  
      android:layout_width="fill_parent"  
      android:layout_height="fill_parent"  
      android:gravity="center_horizontal">  
      <ViewStub   
        android:id="@+id/viewstub_demo_text"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_marginLeft="5dip"  
        android:layout_marginRight="5dip"  
        android:layout_marginTop="10dip"  
        android:layout="@layout/viewstub_demo_text_layout"/>  
      <ViewStub   
        android:id="@+id/viewstub_demo_image"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_marginLeft="5dip"  
        android:layout_marginRight="5dip"  
        android:layout="@layout/viewstub_demo_image_layout"/>  
    </LinearLayout>

为TextView的布局:

[html] view plaincopyprint?

<?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout  
      xmlns:android="http://schemas.android.com/apk/res/android"  
      android:orientation="vertical"  
      android:layout_width="wrap_content"  
      android:layout_height="wrap_content">  
        <TextView  
            android:id="@+id/viewstub_demo_textview"  
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:background="#aa664411"  
            android:textSize="16sp"/>  
    </LinearLayout>

为ImageView的布局:

[html] view plaincopyprint?

<?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout  
      xmlns:android="http://schemas.android.com/apk/res/android"  
      android:orientation="vertical"  
      android:layout_width="wrap_content"  
      android:layout_height="wrap_content">  
        <ImageView  
            android:id="@+id/viewstub_demo_imageview"  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"/>  
    </LinearLayout>

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

[java] view plaincopyprint?

package com.effective;  
      
    import android.app.Activity;  
    import android.os.Bundle;  
    import android.view.ViewStub;  
    import android.widget.ImageView;  
    import android.widget.TextView;  
      
    public class ViewStubDemoActivity extends Activity {  
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.viewstub_demo_activity);  
            if ((((int) (Math.random() * 100)) & 0x01) == 0) {  
                // to show text  
                // all you have to do is inflate the ViewStub for textview  
                ViewStub stub = (ViewStub) findViewById(R.id.viewstub_demo_text);  
                stub.inflate();  
                TextView text = (TextView) findViewById(R.id.viewstub_demo_textview);  
                text.setText("The tree of liberty must be refreshed from time to time" +  
                        " with the blood of patroits and tyrants! Freedom is nothing but " +  
                        "a chance to be better!");  
            } else {  
                // to show image  
                // all you have to do is inflate the ViewStub for imageview  
                ViewStub stub = (ViewStub) findViewById(R.id.viewstub_demo_image);  
                stub.inflate();  
                ImageView image = (ImageView) findViewById(R.id.viewstub_demo_imageview);  
                image.setImageResource(R.drawable.happy_running_dog);  
            }  
        }  
    }

运行结果:

使用的时候的注意事项:

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

【Android 界面效果37】ViewStub的应用的更多相关文章

  1. 【Android 界面效果31】Android--侧滑菜单应用的实现

    侧滑菜单应用现在非常多,而且实现方式也多种多样.通过在网上的多方查找,我找到郭霖少侠的这篇文章:http://blog.csdn.net/guolin_blog/article/details/874 ...

  2. 【Android 界面效果25】android中include标签的使用

    在一个项目中我们可能会需要用到相同的布局设计,如果都写在一个xml文件中,代码显得很冗余,并且可读性也很差,所以我们可以把相同布局的代码单独写成一个模块,然后用到的时候可以通过<include ...

  3. 【Android 界面效果21】Android ViewPager使用详解

    这是谷歌官方给我们提供的一个兼容低版本安卓设备的软件包,里面包囊了只有在安卓3.0以上可以使用的api.而viewpager就是其中之一利用它,我们可以做很多事情,从最简单的导航,到页面菜单等等.那如 ...

  4. 【Android 界面效果18】Android软件开发之常用系统控件界面整理

    [java] view plaincopyprint?   <span style="font-size:18px">1.文本框TextView TextView的作用 ...

  5. 【Android 界面效果17】Android手机平板两不误,使用Fragment实现兼容手机和平板的程序

    记得我之前参与开发过一个华为的项目,要求程序可以支持好几种终端设备,其中就包括Android手机和Android Pad.然后为了节省人力,公司无节操地让Android手机和Android Pad都由 ...

  6. 【Android 界面效果45】ViewPager源码分析

    ViewPager概述: Layout manager that allows the user to flip left and right through pages of data. You s ...

  7. 【Android 界面效果42】如何自定义字体

    项目里要统一用设计师的字体,android:typeface只支持系统三种字体.有什么比较好的做法? 你需要为整个应用替换自定义字体. 解决方案 1)Android默认方法 #1 你可以通过ID查找到 ...

  8. 【Android 界面效果41】Matrix 与 ColorMatrix

    Matrix: 简单用法就是直接使用它的setXX()方法 而高级一点来理解他就是去理解一个线性矩形 首先我们来认识线性矩形:(用画图粗略地画不要见怪) 分析: 那还有一组 MRERSP_0 MRER ...

  9. 【Android 界面效果40】Android4.0-Fragment框架实现方式剖析(一)

    经过反复的学习对比,个人觉得带着问题学习新知是最有效的学习方式,因此文本就以提问的方式来讲述Fragment框架实现方式. 1.什么是Fragment? Fragment包含在Activity中,Fr ...

随机推荐

  1. java之四大皆空

    SE中的所有空的情况: 第一空:定义变量,变量没有值不能使用,不能打印 public class DiDaJieKong01 { public static void main(String[] ar ...

  2. poj 2594 Treasure Exploration(最小路径覆盖+闭包传递)

    http://poj.org/problem?id=2594 Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total ...

  3. 代码SketchPaintCode绘制

    作者:codeGlider 在我的上一篇文章中 swift10分钟实现炫酷的导航控制器跳转动画,有一个swift logo的形状 上一篇文章的动画 我说的就是中间用来做遮罩的形状. 它不是图片是用一段 ...

  4. HDU 5708 Alice and Bob (博弈,找规律)

    题意: 一个无限大的棋盘,一开始在1,1,有三种移动方式,(x+1,y)(x,y+1) (x+k,y+k)最后走到nm不能走了的人算输.. 析:.我们看成一开始在(n,m),往1,1,走,所以自然可以 ...

  5. IE浏览器在虚拟机中无法正常显示字符

    今天在win7虚拟机中安装IE10之后,打开任何页面都无法显示文字,自己找了一些资料也没有什么发现,虚拟机其他的程序都能很好的工作,只有IE10有问题,于是初步怀疑是IE10设置的问题.于是打开IE的 ...

  6. 解决CSS各种IE各种兼容问题(Google解决方案)

    google的 ie7 – js中是一个JavaScript库(解决IE与W3C标准的冲突的JS库),使微软的Internet Explorer的行为像一个Web标准兼容的浏览器,支持更多的W3C标准 ...

  7. C:指针、数据类型、格式化输入输出、输入函数的坑点

    指针.数据类型.格式化输入输出.输入函数的坑点 有时候我们迷茫的时候,坚持就是最好的选择. 1.指针的分类为什么很重要? 参考 答:因为指针会根据相应的类型取对应长度的数据,类型决定所取数据的长度.如 ...

  8. gif动态图片去白边,杂边

    (从已经死了一次又一次终于挂掉的百度空间人工抢救出来的,发表日期2014-05-30)

  9. mybatis 注解快速上手

    一.mybatis 简单注解 关键注解词 : @Insert : 插入sql , 和xml insert sql语法完全一样 @Select : 查询sql, 和xml select sql语法完全一 ...

  10. 今天做php经典实例,发现,我是对的,面试官给我说错了

    那是七月中下旬在乐元素公司面试,问了我问什么 $str = "Hellow {$res} world";这么写,我回答说 在字符串中插入复杂变量可以用花括号干起来把? 他告诉我 应 ...