ViewStub讲给小白的入门知识

ViewStub是啥?干啥的?

ViewStub是一个轻量级的View,为啥说轻量级,因为他的大小为0,没有尺寸,也不绘制任何东西。
那他是干啥的呢,一个View不绘制东西有何意义,其实是用来延迟加载的,也可以理解为他就是用来占位置的(先把位置选了,需要的时候在把要显示的View加载出来)。

如何显示要显示的View呢?

根据他的文档所说,有两种方式呈现出你想要的View:

A ViewStub is an invisible, zero-sized View that can be used to
lazily inflate layout resources at runtime. When a ViewStub is made
visible, or when inflate() is invoked, the layout resource is inflated.
The ViewStub then replaces itself in its parent with the inflated View
or Views. Therefore, the ViewStub exists in the view hierarchy until
setVisibility(int) or inflate() is invoked. The inflated View is added
to the ViewStub’s parent with the ViewStub’s layout parameters.
Similarly, you can define/override the inflate View’s id by using the
ViewStub’s inflatedId property.

就是说可以使他visible(也就是调用setVisibility()方法),或者调用inflate()方法,这个ViewStub将会被替换掉,被你所要显示的View

优缺点

优点
实现View的延迟加载,避免资源的浪费,减少渲染时间,在需要的时候才加载View

缺点
ViewStub所要替代的layout文件中不能有merge标签
ViewStub在加载完后会被移除,或者说是被加载进来的layout替换掉了

注意:

1、ViewStub 的inflate() 只能被调用一次!(会报错ViewStub must have a non-null ViewGroup viewParent)setVisibility可以被调用多次

2、在xml的布局文件中 ViewStub标签下必须设置android_layout:属性(注意不是layout前面一定要有android), 否则会报错ViewStub must have a valid layoutResource

3、 一定要在inflate或者setVisibility后去使用findViewById ,否则会报空指针

关于布局中的inflatedId

其中inflatedId就是新加载进来的view的id,如果需要获取这个view,就要用这个inflatedId,原来的ViewStub的id已经被取代了(这个我没怎么用,所以没太理解这个的作用,因为你的要显示的View的跟布局中的id如果设置了会覆盖掉这个,所以我不知道又啥其他的作用)

看看怎么使用吧
1、搭建有ViewStub的xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.a_0102.mylearn.view.ViewStubActivity">

    <ViewStub
        android:id="@+id/vs_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout="@layout/layout_item" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/blue"
        android:gravity="center"
        android:text="我是TextView"
        android:textSize="20sp" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="clickInflated"
        android:text="调用Inflated" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="clicksetVisibily"
        android:text="调用setVisibily" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="clickGone"
        android:text="隐藏View" />
</LinearLayout>

2、ViewStub要替代的View的布局,在代码中是layout_item的布局

<?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="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_text"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="阿哈哈哈"
        android:gravity="center"/>
</LinearLayout>

3、整体的逻辑

/**
 * ViewStub学习
 * <p>
 * 介绍
 * ViewStub 是一个轻量级的View,没有尺寸,不绘制任何东西,因此绘制或者移除时更省时。(ViewStub不可见,大小为0)
 * <p>
 * 优点
 * 实现View的延迟加载,避免资源的浪费,减少渲染时间,在需要的时候才加载View
 * <p>
 * 缺点
 * ViewStub所要替代的layout文件中不能有<merge>标签
 * ViewStub在加载完后会被移除,或者说是被加载进来的layout替换掉了
 * <p>
 * 布局中的inflatedId
 * 其中inflatedId就是新加载进来的view的id,如果需要获取这个view,就要用这个inflatedId,原来的id已经被取代了
 * <p>
 * <p>
 * ViewStub 的inflate() 只能被调用一次!(会报错ViewStub must have a non-null ViewGroup viewParent)setVisibility可以被调用多次
 * <p>
 * <ViewStub></ViewStub>标签中必须设置android_layout:属性, 否则会报错ViewStub must have a valid layoutResource
 */
public class ViewStubActivity extends AppCompatActivity {

    private ViewStub mVsTestView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_stub);
        mVsTestView = findViewById(R.id.vs_test);
    }

    //调用了setVisibily后也不能在调用inflate了
    public void clickInflated(View view) {
        mVsTestView.inflate();
        ((TextView) findViewById(R.id.tv_text)).setText("我是ViewStub替换出来的View");
    }

    public void clicksetVisibily(View view) {
        mVsTestView.setVisibility(View.VISIBLE);
        ((TextView) findViewById(R.id.tv_text)).setText("我是ViewStub替换出来的View");
    }

    public void clickGone(View view) {
        mVsTestView.setVisibility(View.GONE);
        ((TextView) findViewById(R.id.tv_text)).setText("我已经隐藏了");
    }
}

首先通过inflate()显示,可以政策的隐藏,然后可以再次通过setVisibility再次显示,这个里面说明了inflate只能调用一次,多次调用会报错,但是setVisibility可以多次调用。

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值