ViewStub惰性装载控件

     我们知道Android中的<include>标签,该标签可以在布局文件当中引用另外一个布局文件,这种方式是在布局文件中固定导入,使用起来不是很方便。

     ViewStub的功能和<include>的功能类似,也是实现引用另外一个布局。但是唯一不同的是ViewStub并不会马上装载引用布局文件,只有在调用了ViewStub.inflate();或ViewStub.setVisibilty(VISIBLE),ViewStub 才会装载引用的控件。

     ViewStub是一个轻量级的View,它是一个看不见的、不占布局位置、占用资源非常小的控件。我们在用的时候可以为ViewStub制定一个布局,在inflate布局的时候,只有ViewStub会被初始化,然后当ViewStub设置为可见的时候或是调用了ViewStub.inflate()的时候,ViewStub所指向的布局就会被inflate和实例化,然后ViewStub的布局属性都会传给它所指向的布局。这样,就可以使用ViewStub来方便的控制要不要显示某个布局。

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/showBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="动态添加布局" />

        <Button
            android:id="@+id/deleteBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="动态隐藏布局" />
    </LinearLayout>

    <!-- 动态加载布局文件 -->

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <ViewStub
            android:id="@+id/viewstub"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout="@layout/next" />
    </LinearLayout>

</LinearLayout>
next.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <RatingBar
        android:id="@+id/ratingBar1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>
MainActivity.java

package com.example.viewstub;

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 button1, button2;
	private ViewStub viewStub;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        button1 = (Button) findViewById(R.id.showBtn);
        button2 = (Button) findViewById(R.id.deleteBtn);
        viewStub = (ViewStub) findViewById(R.id.viewstub);
        
        button1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// 表示填充动态布局
				viewStub.inflate();
				//viewStub.inflate();方法只能被调用一次,多次点击会出错
				//或者viewStub.setVisibility(View.VISIBLE);可多次点击
			}
		});
        button2.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// 隐藏动态加载的布局
				viewStub.setVisibility(View.GONE);
			}
		});
    }

}
点击“动态添加布局”按钮就会出现下面的UI


点击“动态隐藏布局”按钮就会出现下面的UI


这样就可以了。另外,小编在写的时候还存在一些问题,需要大家注意一下。

1、多次调用inflate()错误

当你多次调用ViewStub.inflate()的时候,已经用ViewStub里面指定的layout代替了ViewStub。换句话说,ViewStub已经不再activity_main.xml里面了,而在inflate()源码里面。

final ViewParent viewParent = getParent();

if (viewParent!=null && viewParent instanceof ViewGroup)

这时候getParent()已经是null了,所以再一次点击会出错。

2、调用viewStub.setVisibility(View.VISIBLE);可多次点击

在源码中super.setVisibility(View.VISIBILE);

inflate();

先不显示,然后次啊调用inflate(),所以ViewStub可能还在activity_main.xml里面,所以getParent()不会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值