[ACCEPTED]-How to check if a viewStub is already inflated?-viewstub

Accepted answer
Score: 30

We can view the ViewStub source code, the most important 4 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 3 in layout after inflate.so we can check 2 if a viewStub is already inflated by this 1 way.

if (mViewStub.getParent() != null) {
    mViewStub.inflate();
} else {
    mViewStub.setVisibility(View.VISIBLE);
}
Score: 6
if (mViewStub.getParent() != null) { 
    //have not been inflated
    mViewStub.inflate();
} else { 
    //already inflated
}

0

Score: 3

note from google:

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

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

Score: 1

A more simple approach, in Kotlin:

if (viewStub != null) {
   viewStub.isVisible = true
} else {
   // The view has been inflated already.
}

0

Score: 1

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()
}

0

Score: 0

you can use this in Kotlin.. i know that 3 it uses tag (its not cool) but its easy 2 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 1 you can use it like this :

 myViewStub.doInflate({
            //code that run with initialisation
        }, {
           //code that run if stub already inflated
        })
Score: 0

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

so 1 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)
}

More Related questions