How to check if a viewStub is already inflated?
Asked Answered
E

8

20

I did not find any boolean method does this task. Can I do this by checking if the id of the viewStubchanged to the one specified as inflatedid?

Javacode:

    protected void plantViewTree() {
    // TODO Auto-generated method stub

        ViewStub mViewstub = (ViewStub) findViewById(R.id.viewStub00);

            if (mViewStub is inflated) {
              //do somthing
              }else
               mViewstub.inflate();

}

Update Comments on th eOutput

According to this code, the toast always displays its message, which mean since mViewStub is assigned to findViewById it is never null except the viewstub view in the underlaying alyout is not available. Any suggestions.?

protected void plantViewTree() {
    // TODO Auto-generated method stub
    ViewStub mViewstub = (ViewStub) findViewById(R.id.viewStub00);
    if (mViewstub != null)
        Toast.makeText(getApplicationContext(), "view is inflated", 
Toast.LENGTH_LONG).show();
    else
        mViewstub.inflate();
}
Euphemize answered 21/5, 2014 at 12:25 Comment(1)
If it is not inflated, it will be null. You can check if it is null or not.Corbitt
G
30

We can view the ViewStub source code, the most important method is inflate(),

 public View inflate() {
    final ViewParent viewParent = getParent();

    if (viewParent != null && viewParent instanceof ViewGroup) {
        if (mLayoutResource != 0) {
            final ViewGroup parent = (ViewGroup) viewParent;
            final LayoutInflater factory;
            if (mInflater != null) {
                factory = mInflater;
            } else {
                factory = LayoutInflater.from(mContext);
            }
            final View view = factory.inflate(mLayoutResource, parent,
                    false);

            if (mInflatedId != NO_ID) {
                view.setId(mInflatedId);
            }

            final int index = parent.indexOfChild(this);
            parent.removeViewInLayout(this);

            final ViewGroup.LayoutParams layoutParams = getLayoutParams();
            if (layoutParams != null) {
                parent.addView(view, index, layoutParams);
            } else {
                parent.addView(view, index);
            }

            mInflatedViewRef = new WeakReference<View>(view);

            if (mInflateListener != null) {
                mInflateListener.onInflate(this, view);
            }

            return view;
        } else {
            throw new IllegalArgumentException("ViewStub must have a valid layoutResource");
        }
    } else {
        throw new IllegalStateException("ViewStub must have a non-null ViewGroup viewParent");
    }
}

Notice this line parent.removeViewInLayout(this) ,it had removed in layout after inflate.so we can check if a viewStub is already inflated by this way.

if (mViewStub.getParent() != null) {
    mViewStub.inflate();
} else {
    mViewStub.setVisibility(View.VISIBLE);
}
Glucoprotein answered 6/2, 2015 at 10:27 Comment(1)
to see does viewstub finish it's work just check, mViewStub.getParent() != null, if it is not finish it's work parent will be != null otherwise parent will be nullKynthia
V
7
if (mViewStub.getParent() != null) { 
    //have not been inflated
    mViewStub.inflate();
} else { 
    //already inflated
}
Vibraphone answered 7/9, 2017 at 8:7 Comment(0)
T
3

note from google:

When a ViewStub is made visible, or when inflate() is invoked, the layout resource is inflated.

so you can check the visibility (or even checking if it's "null").

Tomekatomes answered 21/5, 2014 at 12:44 Comment(1)
that is not true, viewstub is not null when it is inflatedKynthia
E
2

You can use this extension:

/**
 * To prevent crash when we try inflate view that was already inflated. Because OS delete ViewStub by inflating.
 */
fun ViewStub?.safeInflate() {
    if (this?.parent != null) inflate()
}
Erring answered 1/2, 2021 at 14:57 Comment(0)
R
1

A more simple approach, in Kotlin:

if (viewStub != null) {
   viewStub.isVisible = true
} else {
   // The view has been inflated already.
}
Radack answered 9/7, 2018 at 2:25 Comment(0)
K
0

you can use this in Kotlin.. i know that it uses tag (its not cool) but its easy to use. this is kotlin extension function:

fun ViewStub.doInflate(init: View.() -> Unit = {}, action: (View) -> Unit = {}) {
val isInflated = (tag as? Boolean) ?: false
if (!isInflated) {
    setOnInflateListener { _, view ->
        this.tag = true
        init.invoke(view)
        action.invoke(view)
    }
    this.inflate()
} else {
    action.invoke(this.rootView)
}

}

and you can use it like this :

 myViewStub.doInflate({
            //code that run with initialisation
        }, {
           //code that run if stub already inflated
        })
Kalasky answered 23/12, 2018 at 6:12 Comment(0)
U
0

As the documentation suggests, we should not keep a long lived reference to the ViewStub, and android also allows assigning an inflatedId to ViewStub, which comes into existence once its inflated

so we can have a function signature like getInflatedView(): View

fun getInflatedView(@LayoutRes layoutId: Int): View {
    val stub: ViewStub? = findViewById(R.id.stubId)
    stub?.layoutResource = layoutId
    return stub?.inflate() ?: findViewById(R.id.inflatedId)
}
Unpleasantness answered 4/6, 2019 at 19:38 Comment(0)
G
-2

Calling yourViewStub.visibility(View.VISIBLE) you don´t need to check if it´s inflated or not.

Greisen answered 5/8, 2016 at 2:30 Comment(1)
Got the same crush.Bedspread

© 2022 - 2024 — McMap. All rights reserved.