This might seem like a very obvious thing to most, but for me it was not. In some code I’ve inherited, ViewStub is used a great deal and works well, except for when I was trying to resolve the root element of the inflated content. For example the following (greatly simplified) setup:
Host view XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/content" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1"> <ViewStub android:id="@id/stub_import" android:inflatedId="@id/content_import" android:layout="@layout/splash" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </RelativeLayout> </LinearLayout> </pre> <!--more--> <h4>Content View XML</h4> <pre class="prettyprint lang-xml"> <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:id="@+id/root_control"> <LinearLayout android:id="@+id/some_sub_control" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> </LinearLayout> </LinearLayout>
Then in the your Activity:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewStub stub = (ViewStub)this.findViewById(R.id.stub_import); stub.setInflatedId(R.id.content_import); stub.setLayoutResource(R.layout.content); stub.inflate(); // rootElement will be null!! LinearLayout rootElement = (LinearLayout)this.findViewById(R.id.root_control); // subControl holds a reference to the expected control. LinearLayout subControl = (LinearLayout)this.findViewById(R.id.some_sub_control); }
So what’s going on here? Well three things really! Mostly that I should pay attention more and not rush so much. Those small details you can easily overlook often turn out to be the cause of your problems. The other two things are pretty much the same thing:
android:inflatedId="@id/content_import" // From the Java code stub.setInflatedId(R.id.content_import);
So here, they’re instructing the ViewStub to give the inflated content a new id once the ViewStub has been replaced. Great! Why they did it twice is anyone’s guess but that was the problem. Remove that code and hey presto! It works as expected. Also, another handy tip is that you can also get a reference to the inflated content via the result of the call to inflate().
LinearLayout rootElement = (LinearLayout)stub.inflate(); // Gets you the same thing as... LinearLayout rootElement = (LinearLayout)this.findViewById(R.id.root_control);