ViewStub

ViewStub是一个有利于节省布局资源的控件,当布局中一些元素不需要一开始就加载的时候,我们可以让他先处于“休眠”状态,等需要时再加载上来。之前一直没有接触使用过,最近项目中遇到一个场景突然可以用。

场景是:进入页面后会搜索本地音乐,如果没有本地音乐,那么将显示一个占位图。这是一个非常常见的场景,之所以想到用ViewStub,是因为占位图非常之大,虽然不至于撑破你的内存,但是能省就省吧,更何况对于大多数用户来说,根本就看不到这个图。


ViewStub特点:

ViewStub 在没被加载之前,是一个很空的View,空到连大小都没有

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(0, 0);
    }

infalte 会把指向的 layout 加载到自己所在的parent上,并移除自己(传说中的千斤顶?)
所以ViewStub非常适合用于节省布局的消耗


基本使用:

在布局中:

    

layout 是必须要指定的。这里的 visibility 无论设置什么最后都会是 GONE

源码中你会看到

  public ViewStub(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context);

        final TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.ViewStub, defStyleAttr, defStyleRes);
        mInflatedId = a.getResourceId(R.styleable.ViewStub_inflatedId, NO_ID);
        mLayoutResource = a.getResourceId(R.styleable.ViewStub_layout, 0);
        mID = a.getResourceId(R.styleable.ViewStub_id, NO_ID);
        a.recycle();

        setVisibility(GONE);    //就是这里
        setWillNotDraw(true);
  }

在代码中,你可以调用 viewstub.inflate() 来加载它

当然更简单的就是 viewstub.setVisibility() 内部会处理

public void setVisibility(int visibility) {
        if (mInflatedViewRef != null) {
            View view = mInflatedViewRef.get();
            if (view != null) {
                view.setVisibility(visibility);
            } else {
                throw new IllegalStateException("setVisibility called on un-referenced view");
            }
        } else {
            super.setVisibility(visibility);
            if (visibility == VISIBLE || visibility == INVISIBLE) {
                inflate();  //基本知识:VISIBLE 和 INVISIBLE 都是被加载的
            }
        }
    }

你可能关心的:

viewstub 中的 view 需要被 infalte() 之后才能通过 findviewbyid 去找到,那么如果需要设置监听就在再 setVisibility() 之后?那也太蠢了吧!

本来想模仿 view.post() 写一个 runablesetVisibility() 之后跑

结果 VIewStubfinal 的(绝望)

结果看源码的时候(总共才300行)发现。。 原来人家是有监听给你的

setOnInflateListener()

僵硬- -

转眼间从事安卓开发已经一年多了,期间写了无数的自定义控件,各种复杂的交互动画,因为项目需要也自学了OpenGLES(《图片合成器》 - 已离职),但一直没有在GitHub上分享过自己的代码,今天第一篇算是一个起点,希望能有帮助,有什么问题也欢迎留言,共同学习,共同进步。

你可能感兴趣的:(ViewStub)