Android ViewStub change layouts programmatically
A ViewStub is a placeholder, which is replaced by an inflated layout as soon as ViewStub.inflate() is called. It doesn't make sense to call inflate a second time, as the ViewStub will no longer be in the hierarchy. Instead, you should obtain a reference to your LinearLayout, remove its views, and add your second layout as a child.
ViewStub stub = (ViewStub) findViewById(R.id.layout_stub);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
stub.setLayoutResource(layoutId);
stub.inflate(); // inflate 1st layout
ll.removeAllViews(); // remove previous view, add 2nd layout
ll.addView(LayoutInflater.from(context).inflate(secondLayoutId, ll, false));
Yes, I think you can easily replace it with another ViewStub and lazily inflate your new layout in this way:
for Java
public static ViewStub deflate(View view) {
ViewParent viewParent = view.getParent();
if (viewParent != null && viewParent instanceof ViewGroup) {
int index = ((ViewGroup) viewParent).indexOfChild(view);
int inflatedId = view.getId();
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
((ViewGroup) viewParent).removeView(view);
Context context = ((ViewGroup) viewParent).getContext();
ViewStub viewStub = new ViewStub(context);
viewStub.setInflatedId(inflatedId);
viewStub.setLayoutParams(layoutParams);
((ViewGroup) viewParent).addView(viewStub, index);
return viewStub;
} else {
throw new IllegalStateException("Inflated View has not a parent");
}
}
or Kotlin with an extension
fun ViewStub.deflate(view: View): ViewStub {
val viewParent = view.parent
if (viewParent != null && viewParent is ViewGroup) {
val index = viewParent.indexOfChild(view)
viewParent.removeView(view)
val viewStub = ViewStub(context).apply {
inflatedId = [email protected]
layoutParams = [email protected]
}
viewParent.addView(viewStub, index)
return viewStub
} else {
throw IllegalStateException("Inflated View has not a parent")
}
}
Check out the gist