How to "deflate" a ViewStub?
Asked Answered
P

3

29

So I can inflate a ViewStub at runtime. Let's say I want to make it disappear and then maybe inflate again depending on some event occurring (for example, a toolbar that inflates and deflates according to what the user selects on screen).

I can use View.setVisibility(View.GONE).... is there any other way?

Or am I doing something wrong here?

Thanks! :)

Pascha answered 1/10, 2010 at 19:22 Comment(3)
setVisibility(View.GONE) is a bit more descriptive.Duer
What don't you like about View.GONE?Greensboro
I don't dislike it. Was just wondering if this IS the correct way to do it, or is there some other efficient way?Pascha
G
37

Inflating layouts can be expensive, especially on older devices. Think of ViewStub as more of a lazy-loading mechanism for view subtrees that may or may not ever get expanded rather than a way to swap out sections of a view hierarchy at runtime. Once inflated, there's nothing wrong with swapping between VISIBLE/GONE. GONE will make the framework skip that subtree during expensive traversals.

This is true as long as you don't need the memory used by the inflated view. Setting visibility to GONE doesn't release any memory whatsoever; it only marks the view as gone for layout and drawing purposes. To release the memory of the viewstub's inflated view, you would have actually to remove the inflated view and replace it again with a new viewstub for future use.

Galiot answered 1/10, 2010 at 22:19 Comment(1)
hello @Galiot I have one doubt. what if I create one simple linear layout and add one child view dynamically in it and when I don't need it I remove that child view from linear layout in this way it will remove child view completely. Is it good approach when you want memory optimization? because once view stub inflated we can't remove that view just by make it GONE.Hellas
P
0

Yes you can remove whenver you want .i have done it just now.

ViewStub stub = findById(...);
View v = stub.inflate();

and set view visibility on any event.

v.setVisibility(View.GONE);
Populace answered 12/5, 2011 at 9:16 Comment(1)
Setting the visibility to GONE doesn't remove it, it merely hides it.Frostbitten
E
0

Here's some code that deflates a view stub:

private Boolean isErrorViewInflated = false;
private ViewStub errorViewStub;  
/* here a method that gets a view.  If the view is already inflated,
 * it uses that view, else it inflates the view. It also creates a viewStub
 * object which will be used to replace the inflated view when it needs to 
 * be deflated.
 /
public RelativeLayout getErrorView() {
    RelativeLayout errorView = null;
    if (isErrorViewInflated) {
        errorView = activity.findViewById(R.id.error_view);
    } else {
        ViewStub stub = activity.findViewById(R.id.error_view_stub);
        errorView = (RelativeLayout) stub.inflate();
        errorViewStub = new ViewStub(getContext(), stub.getLayoutResource());
        isErrorViewInflated = true;
    }
    return errorView;
}

/* Here's the code that deflates an inflated ErrorView back to a ViewStub
 */
private void deflateErrorView() {
    if (isErrorViewInflated) {
        RelativeLayout errorView = activity.findViewById(R.id.error_view);
        ViewGroup parent = (ViewGroup)errorView.getParent();
        int index = parent.indexOfChild(errorView);
        parent.removeView(errorView);
        parent.addView(errorViewStub, index);
        isErrorViewInflated = false;
    }
}

If you're wondering, you can't just cache the original ViewStub and use it to replace the inflated view. That's because the original ViewStub object had a parent View and you get an error if you try to add that view into any view group (even if it's the same view group it was originally contained in). So, the way around this issue is to create a new ViewStub object using the same layout resource as in the original ViewStub.

If you're not concerned about the space occupied by an inflated ViewStub when that inflated ViewStub is no longer needed, then the "View.GONE" solution is fine. There's no significant runtime overhead for views whose visibility is set to GONE. In my case, I've been using ViewStub's for errors, logs and console display areas and I want the system to be able to garbage collect the objects associate with those views when they are not in use.

Execratory answered 22/9, 2023 at 17:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.