Android在layout xml中使用ViewStub完成动态加载
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而做的布局:
- <?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的布局:
- <?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的布局:
- <?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()就可以获得相应想要的布局:
- 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()后会都传给相应的布局。
参考:http://blog.csdn.net/hitlion2008/article/details/6737537/
Android在layout xml中使用ViewStub完成动态加载的更多相关文章
- Android在layout xml中使用include完成静态加载
Android在layout xml中使用include完成静态加载 include静态加载:不仅可以加载布局,还可以加载控件(控件标签名要在最外层)include标签中有个layout属性就是专门用 ...
- Android在layout xml中使用include
Android include与merge标签使用详解 - shuqiaoniu的博客 - 博客频道 - CSDN.NEThttp://blog.csdn.net/shuqiaoniu/article ...
- Android中插件开发篇之----动态加载Activity(免安装运行程序)
一.前言 又到周末了,时间过的很快,今天我们来看一下Android中插件开发篇的最后一篇文章的内容:动态加载Activity(免安装运行程序),在上一篇文章中说道了,如何动态加载资源(应用换肤原理解析 ...
- 关于Android中Fragment静态和动态加载的方法
一.静态加载 1.首先创建一个layout布局fragment.xml,里面放要显示和操作的控件 2.创建一个layout布局main1.xml,用来实现页面的跳转(跳转为要实现静态加载的界面) 3. ...
- Silverlight实用窍门系列:2.Silverlight动态加载外部XML指定地址的WebService---(动态加载外部XML文件中指定的WebService地址)【附带实例源码】
接上节所讲的,Silverlight可以加载外部的XML文件里面的内容,那么我们可不可以在外部XML里面配置一个WebService地址,并且以此加载这个地址来动态加载WebService呢?这样子就 ...
- Android在layout xml中使用include[转]
在Android的layout样式定义中,可以使用xml文件方便的实现,有时候为了模块的复用,使用include标签可以达到此目的.例如: <include layout="@layo ...
- web.xml中如何设置配置文件的加载路径
web应用程序通过Tomcat等容器启动时,会首先加载web.xml文件,通常我们工程中的各种配置文件,如日志.数据库.spring的文件等都在此时被加载,下面是两种常用的配置文件加载路径,即配置文件 ...
- web.xml中servlet, bean, filter, listenr 加载顺序汇总
最终得出结果:先 listener >> filter >> servlet >> spring 所以,如果过滤器中要使用到 bean,可以将spring 的加载 ...
- 如何在在WinFrom的DataGridView中做到数据持续动态加载而不卡死
1.在这个过程我用过好几种办法 (1)使用委托的办法,这个方法可以做到持续加载,但是效果不理想会卡死 (2)开启线程的方法,会造成卡死 (3)使用另一个窗体的线程做持续加载(子窗体),让子窗体作为一个 ...
随机推荐
- 学习 Tornado
异步编程 预习 lambda Lambda functions can be used wherever function objects are required. They are syntact ...
- linux linux 互传文件 win 不通过 ftp sftp 往linux 传文件(文件夹)
linux 传入 传出文件 swp port 22 怎样通过swp通过docker 容器向外传文件 通过scp Linux互传文件,需要知道文件源 file source 所在系统的ip wuse ...
- pycharm 调试django 服务端断点调试
django runserver 服务端断电调试 D:\model\gitlab\eebo.ehr.analysis\venv\Scripts\python.exe "C:\Program ...
- Python星号*与**用法分析 What does ** (double star/asterisk) and * (star/asterisk) do for parameters? 必选参数 默认参数 可变参数 关键字参数
python中*号**的区别 - CSDN博客 https://blog.csdn.net/qq_26815677/article/details/78091452 定义可变参数和定义 list 或 ...
- diff工具
Beyond Compare 4 可以diff文件夹.单个文件.
- Linux运维-zabbix_agent最新版的yum安装
agentd端可以直接使用yum来进行安装 rpm -ivh http://repo.zabbix.com/zabbix/2.4/rhel/6/x86_64/zabbix-release-2.4-1. ...
- 前端基础-html(2)
一.字体标签 字体标签包含:h1~h6.<font>.<u>.<b>.<strong>.<em>.<sup>.<sub&g ...
- Ubuntu系统vi编辑器上下左右键变ABCD的解决方法(转)
首先卸载旧版本的vi编辑器: $sudo apt-get remove vim-common 然后安装新版vi即可: $sudo apt-get install vim Ubuntu自带有几种版本的v ...
- 集成富文本编辑器XSS预防过滤措施
# https://github.com/phith0n/python-xss-filter import re import copy from html.parser import HTMLPar ...
- 剑指offer 面试21题
面试21题: 题目:调整数组的顺序使奇数位于偶数前面 题一:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分. 解题思路:使用两个指针 ...