Android在layout xml中使用ViewStub完成动态加载

一、Layout XML文件常见的两种模块加载方式

  1、静态加载:被加载的模块和其它模块加载的时间一样。
    <include layout="@layout/otherLayout"/>

  2、动态加载:需要被加载的模块初始时并没有被加载进内存,在你需要加载这个模块才会被动态的加载进去。
    <ViewStub android:layout="@layout/otherLayout"/>

    还要把layout width和height加上

  

二、ViewStup完成动态加载

  1、简介

      

  2、ViewStub类结构图

    

    从这个图里面我们可以发现ViewStub是一个控件。是控件那就好办了,那么对其它控件可以进行的操作(例如:初始化,创建对象使用)

    它都可以进行。

    ViewStub是一个控件,所以属性都是android下的,包括layout

    所以我们可以实现用一个button控制ViewStub的动态加载。

  3、ViewStub属性方法

    

    inflate()方法用来加载ViewStub。

    动态功能的实现可以通过在Button的onClick方法里面添加这个inflate()。


三、ViewStub详细介绍

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

参考:http://blog.csdn.net/hitlion2008/article/details/6737537/

  

Android在layout xml中使用ViewStub完成动态加载的更多相关文章

  1. Android在layout xml中使用include完成静态加载

    Android在layout xml中使用include完成静态加载 include静态加载:不仅可以加载布局,还可以加载控件(控件标签名要在最外层)include标签中有个layout属性就是专门用 ...

  2. Android在layout xml中使用include

    Android include与merge标签使用详解 - shuqiaoniu的博客 - 博客频道 - CSDN.NEThttp://blog.csdn.net/shuqiaoniu/article ...

  3. Android中插件开发篇之----动态加载Activity(免安装运行程序)

    一.前言 又到周末了,时间过的很快,今天我们来看一下Android中插件开发篇的最后一篇文章的内容:动态加载Activity(免安装运行程序),在上一篇文章中说道了,如何动态加载资源(应用换肤原理解析 ...

  4. 关于Android中Fragment静态和动态加载的方法

    一.静态加载 1.首先创建一个layout布局fragment.xml,里面放要显示和操作的控件 2.创建一个layout布局main1.xml,用来实现页面的跳转(跳转为要实现静态加载的界面) 3. ...

  5. Silverlight实用窍门系列:2.Silverlight动态加载外部XML指定地址的WebService---(动态加载外部XML文件中指定的WebService地址)【附带实例源码】

    接上节所讲的,Silverlight可以加载外部的XML文件里面的内容,那么我们可不可以在外部XML里面配置一个WebService地址,并且以此加载这个地址来动态加载WebService呢?这样子就 ...

  6. Android在layout xml中使用include[转]

    在Android的layout样式定义中,可以使用xml文件方便的实现,有时候为了模块的复用,使用include标签可以达到此目的.例如: <include layout="@layo ...

  7. web.xml中如何设置配置文件的加载路径

    web应用程序通过Tomcat等容器启动时,会首先加载web.xml文件,通常我们工程中的各种配置文件,如日志.数据库.spring的文件等都在此时被加载,下面是两种常用的配置文件加载路径,即配置文件 ...

  8. web.xml中servlet, bean, filter, listenr 加载顺序汇总

    最终得出结果:先 listener >> filter >> servlet >> spring 所以,如果过滤器中要使用到 bean,可以将spring 的加载 ...

  9. 如何在在WinFrom的DataGridView中做到数据持续动态加载而不卡死

    1.在这个过程我用过好几种办法 (1)使用委托的办法,这个方法可以做到持续加载,但是效果不理想会卡死 (2)开启线程的方法,会造成卡死 (3)使用另一个窗体的线程做持续加载(子窗体),让子窗体作为一个 ...

随机推荐

  1. 数组中binarySearch 中小小的误区! 用的时候大家要注意点

  2. Slyce,这家硅谷创业公司的来头你知道吗

    Slyce,也许你没听过,一家硅谷创业公司,旨在帮助运动员和其他社会名流组织.优化社交媒体,过滤粉丝的声音,让明星更好的在社交媒体上和他们互动.但是如果如果说库里,那你应该就知道了,拿到了上届NBA总 ...

  3. 剑指offer 面试39题

    面试39题: 题目:数组中出现次数超过一半的数字 题:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中 ...

  4. php 计算器的例子

    php实现的计算器的例子,代码如下: <html>     <head>         <title>PHP实现简单计算器-www.jbxue.com</t ...

  5. try catch 事务不会滚

    在spring机制中,在配置事务后,如果采用try catch 捕获异常后,因为异常已经被捕获,所以事务不会滚,从而产生许多脏数据.解决办法: 1.在catch中抛出异常,(throw new Run ...

  6. 前端之 JQuery

    一.基本选择器 1.#id 概述: 根据给定的ID匹配一个元素. 使用任何的元字符(如 !"#$%&'()*+,./:;<=>?@[\]^`{|}~)作为名称的文本部分, ...

  7. linux常用技巧(资料)

    Linux中查看程序安装位置 如果是rpm的安装,用rpm -ql如果是一般安装 用 whereis 或者 find find /usr -name catalina.out======== 如何查看 ...

  8. 微信小程序相关资料整理

    微信小程序官方介绍https://mp.weixin.qq.com/debug/wxadoc/introduction/index.html?t=201818 微信小程序开发资源https://jue ...

  9. PHPExcel常用属性使用

    PHPExcel常用属性使用  前景: 需先实例化几个变量: $this->objExcel = new PHPExcel(); //实例化一个PHPExcel变量 $this->objE ...

  10. Ag-grid控件使用pine:left后,配合iview下拉框,会出现闪烁

    Ag-grid控件使用pinned:left后,配合iview下拉框,会出现闪烁 引起原因:下拉图标的反转动画 目前解决方案: 添加一个全局样式: 禁用动画,其他地方也是如此, 影响控件有:gz-tr ...