首页 > 代码库 > New UI-<ViewStub>标签延时加载布局

New UI-<ViewStub>标签延时加载布局

New UI-<ViewStub>标签延时加载布局

 ——转载请注明出处:coder-pig,欢迎转载,请勿用于商业用途!


小猪Android开发交流群已建立,欢迎大家加入,无论是新手,菜鸟,大神都可以,小猪一个人的

力量毕竟是有限的,写出来的东西肯定会有很多纰漏不足,欢迎大家指出,集思广益,让小猪的博文

更加的详尽,帮到更多的人,O(∩_∩)O谢谢!

小猪Android开发交流群:小猪Android开发交流群群号:421858269

新Android UI实例大全目录:http://blog.csdn.net/coder_pig/article/details/42145907



本节引言:

学习完上一节的include布局复用以后,相信大家都体会到了布局优化的好处,

不过当我们include的布局是一些复杂控件的话,而这些控件我们在实际使用

过程中又用得不多的话,往往会降低页面的加载速度;虽然,我们也可以为其设置

visibility = "gone"的属性,但是在inflate布局的时候,这些控件依旧会被inflate,

也就是说依旧会创建对象,会被实例化,设置属性等,依旧会耗费内存资源,

那么在本节中,我们就来介绍一个轻量级的view:ViewStub

让你的布局在你需要的时候再加载(延时加载)

好了,开始本节内容~




本节正文:


什么是ViewStub?

ViewStub是一个轻量级的View,在布局中不占用任何控件,也不参加
布局的计算与绘制(又叫渲染),可以理解为控件树上的一个
占位符,
仅仅是占着那个位置,没有东西,当我们需要的时候,他才会被渲染(加载)
到主界面上,这种行为也叫做延迟加载,也有人称为"惰性的include"


在什么地方使用?

当我们的app中某个布局,我们并不需要把所有的内容都展示出来,可以隐藏一些View视图,

等需要展示的时候再加载,这个时候就可以用到ViewStub了,有点类似于visibility = "gone",

但是不会随布局进行加载,使用例子如下:(点击listview的item后才加载下方的布局)

技术分享


怎么用?

1)布局中加入<ViewStub标签>

<ViewStub
        android:id="@+id/stub_add"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:inflatedId="@+id/ly_add"
        android:layout="@layout/ly_test" />

三个关键属性:

id:设置ViewStub的引用id
inflatedId:设置加载后的布局对应的id
layout:要加载的那个布局

ps:第二个属性是可选的,当我们的ViewStub加载后,我们就可以直接通过findViewById(R.id.~)

找到加载的那个布局的对应的对象,~是inflatedId的id!因为ViewStub只能用一次!!!!



2)在加载布局文件的Activity中:

方法一:通过findViewById找到ViewStub对象后,调用该对象的inflate()方法:

ViewStub stub = (ViewStub) findViewById(R.id.stub_add);  

stub.inflate(); 


方法二:通过改变ViewStub对象的visibility属性

ViewStub stub = (ViewStub) findViewById(R.id.stub_add);  

stub.setVisibility(View.VISIBLE);

上面写完后,我们如果获得加载布局的对应对象的话,则要通过findViewById(R.id.inflatedId里的id);

找到对应的布局对象了:

View ly_add = (View)findViewById(R.id.ly_add);



处了上面这种写法还,还有一种写法:

因为ViewStub加载完他引用的布局后,他会从控件树中移除,

所以如果你想对引入后的布局进行相关操作的话,那么还是拿一个View来

放着这个布局吧!所以也可以用下面这种写法:

ViewStub stub = (ViewStub) findViewById(R.id.stub_add);  

View view =  stub.inflate(); 

或者:

ViewStub stub = (ViewStub) findViewById(R.id.stub_add);  

View view = stub.setVisibility(View.VISIBLE);


好了,至于用哪种,你自己喜欢了!技术分享



使用ViewStub要注意的地方:

1)ViewStub只能inflate一次,之后ViewStub对象会被置空所以在编写代码

的时候,就不要使用生命周期很长的变量来引用ViewStub控件了,按照上面的教的写法即可!

2)ViewStub加载的只能是布局文件的id,而非某个View



代码示例:

从"惰性include"这个别名,我们就可以知道ViewStub和include其实是类似的

不过前者并不随着布局的渲染和渲染,而是,在我们Inflate或设置Visibility为VISIBLE时

才渲染,而且只用一次,针对的是一次性的东西,在ListView那里用得较多,

当然见仁见智,这里就演示下简单的用法吧:

效果图:

技术分享


报错结束了,恩,别着急,先贴下代码:

actvitiy_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.jay.example.test.MainActivity" >

    <Button
        android:id="@+id/btnLoad"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="加载ViewStub" />

    <Button
        android:id="@+id/btnHide"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="隐藏加载的布局" />

    <Button
        android:id="@+id/btnShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="显示加载的布局" />

    <ViewStub
        android:id="@+id/stub_add"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:inflatedId="@+id/ly_add"
        android:layout="@layout/ly_test" />

</LinearLayout>

引入的布局:ly_test.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.jay.example.test.MainActivity" 
    android:gravity="center">

    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/back"
        android:text="用于测试的ViewStub引入的布局"
        android:textColor="#FFFFFF"
        android:gravity="center_vertical"
        android:textSize="18sp"/>    
</LinearLayout>

MainActivity.java中的代码:

package com.jay.example.test;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewStub;
import android.widget.Button;

public class MainActivity extends Activity {

	private Button btnLoad;
	private Button btnHide;
	private Button btnShow;
	private MyClick myClick;
	private ViewStub viewStub;
	private View view;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		findViews();
		setUpViews();
	}

	private void findViews() {
		btnLoad = (Button) findViewById(R.id.btnLoad);
		btnHide = (Button) findViewById(R.id.btnHide);
		btnShow = (Button) findViewById(R.id.btnShow);
	}

	private void setUpViews() {
		myClick = new MyClick();
		btnLoad.setOnClickListener(myClick);
		btnHide.setOnClickListener(myClick);
		btnShow.setOnClickListener(myClick);
	}

	private class MyClick implements OnClickListener {
		@Override
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.btnLoad:
				viewStub = (ViewStub) findViewById(R.id.stub_add);
				view = viewStub.inflate();
				break;
			case R.id.btnHide:
				view.setVisibility(View.INVISIBLE);
				break;
			case R.id.btnShow:
				view.setVisibility(View.VISIBLE);
				break;
			}
		}
	}

}


代码分析:

代码很简单,要说的问题就是为什么两次加载ViewStub会报错,而且还报了

NullPointerException,这是因为ViewStub只能够inflate一次,用完就没咯

所以后面实现的隐藏和显示的实现就是控制——引入的布局对象!!!




最后说两句:

关于这个ViewStub的使用很简单但也很重要,可能你现在不觉得,但慢慢界面上控件多了,

就知道了,厚积薄发!加油~技术分享






本节参考文献:

http://www.cnblogs.com/plokmju/p/android_viewstub.html

http://blog.csdn.net/mayingcai1987/article/details/6238609

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

https://developer.android.com/reference/android/view/ViewStub.html



New UI-<ViewStub>标签延时加载布局