Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a viewStub is already inflated?

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();
}
like image 211
LetsamrIt Avatar asked May 21 '14 12:05

LetsamrIt


5 Answers

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);
}
like image 73
Folyd Avatar answered Nov 19 '22 10:11

Folyd


if (mViewStub.getParent() != null) { 
    //have not been inflated
    mViewStub.inflate();
} else { 
    //already inflated
}
like image 26
Abhilash Das Avatar answered Nov 19 '22 10:11

Abhilash Das


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").

like image 3
SaDeGH_F Avatar answered Nov 19 '22 11:11

SaDeGH_F


A more simple approach, in Kotlin:

if (viewStub != null) {
   viewStub.isVisible = true
} else {
   // The view has been inflated already.
}
like image 1
Nick Avatar answered Nov 19 '22 10:11

Nick


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()
}
like image 1
Yvgen Avatar answered Nov 19 '22 09:11

Yvgen