Home | History | Annotate | Download | only in articles
      1 page.title=Layout Tricks: Using ViewStubs
      2 parent.title=Articles
      3 parent.link=../browser.html?tag=article
      4 @jd:body
      5 
      6 <p>Sharing and reusing UI components is very easy with Android, thanks to the <a
      7 href="layout-tricks-reuse.html">&lt;include /&gt;</a> tag. Sometimes it's so
      8 easy to create complex UI constructs that your UI ends up with a large number of
      9 views, some of which are rarely used. Thankfully, Android offers a very special
     10 widget called {@link android.view.ViewStub}, which brings you all the benefits
     11 of the <code>&lt;include /&gt;</code> without polluting your user interface with
     12 rarely used views.</p>
     13 
     14 <p>A <code>ViewStub</code> is a dumb and lightweight view. It has no dimension,
     15 it does not draw anything and does not participate in the layout in any way.
     16 This means that a <code>ViewStub</code> is very cheap to inflate and very cheap
     17 to keep in a view hierarchy. A <code>ViewStub</code> can be best described as a
     18 <em>lazy include</em>. The layout referenced by a <code>ViewStub</code> is
     19 inflated and added to the user interface only when you decide so.</p>
     20 
     21 <p>The following screenshot comes from the <a
     22 href="http://code.google.com/p/shelves">Shelves</a> application. The main purpose of
     23 the activity shown in the screenshot is to present the user with a browsable
     24 list of books:</p>
     25 
     26 <img style="margin: 0px auto 10px; display: block; text-align: center;" src="images/viewstub1.png" alt="" id="BLOGGER_PHOTO_ID_5314039375336055346" border="0">
     27 
     28 <p>The same activity is also used when the user adds or imports new books.
     29 During such an operation, Shelves shows extra bits of user interface.
     30 The screenshot below shows the progress bar and cancel button that
     31 appear at the bottom of the screen during an import:</p>
     32 
     33 <img style="margin: 0px auto 10px; display: block; text-align: center;" src="images/viewstub2.png" alt="" id="BLOGGER_PHOTO_ID_5314039800002559378" border="0">
     34 
     35 <p>Because importing books is not a common operation, at least when compared to
     36 browsing the list of books, the import panel is originally represented
     37 by a <code>ViewStub</code>:</p>
     38 
     39 <img style="margin: 0px auto 10px; display: block; text-align: center;" src="images/viewstub3.png" alt="" id="BLOGGER_PHOTO_ID_5314040334008167378" border="0">
     40 
     41 <p>When the user initiates the import process, the <code>ViewStub</code> is 
     42 inflated and replaced by the content of the layout file it references:</p>
     43 
     44 <img style="margin: 0px auto 10px; display: block; text-align: center;" src="images/viewstub4.png" alt="" id="BLOGGER_PHOTO_ID_5314040638747834450" border="0">
     45 
     46 <p>To use a <code>ViewStub</code>, all you need is to specify an 
     47 <code>android:id</code> attribute, to later inflate the stub, and an 
     48 <code>android:layout</code> attribute, to reference what layout file 
     49 to include and inflate. A stub lets you use a third attribute, 
     50 <code>android:inflatedId</code>, which can be used to override the 
     51 <code>id</code> of the root of the included file. Finally, the layout 
     52 parameters specified on the stub will be applied to the roof of the 
     53 included layout. Here is an example:</p>
     54 
     55 <pre class="prettyprint">&lt;ViewStub
     56   android:id="&#64;+id/stub_import"
     57   android:inflatedId="&#64;+id/panel_import"
     58 
     59   android:layout="&#64;layout/progress_overlay"
     60 
     61   android:layout_width="fill_parent"
     62   android:layout_height="wrap_content"
     63   android:layout_gravity="bottom" /&gt;</pre>
     64 
     65 <p>When you are ready to inflate the stub, simply invoke the 
     66 {@link android.view.ViewStub#inflate()} method. You can also simply change the
     67 visibility of the stub to {@link android.view.View#VISIBLE} or 
     68 {@link android.view.View#INVISIBLE} and the stub will inflate. Note however that the
     69 <code>inflate()</code> method has the benefit of returning the root
     70 <code>View</code> of the inflate layout:</p>
     71 
     72 <pre class="prettyprint">((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
     73 // or
     74 View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();</pre>
     75 
     76 <p>It is very important to remember that after the stub is inflated, the stub is
     77 <em>removed</em> from the view hierarchy. As such, it is unnecessary to keep a
     78 long-lived reference, for instance in an class instance field, to a
     79 <code>ViewStub</code>.</p>
     80 
     81 <p>A <code>ViewStub</code> is a great compromise between ease of programming and
     82 efficiency. Instead of inflating views manually and adding them at runtime to
     83 your view hierarchy, simply use a <code>ViewStub</code>. It's cheap and easy.
     84 The only drawback of <code>ViewStub</code> is that it currently does
     85 <em>not</em> support the <a href="layout-tricks-merge.html">&lt;merge /&gt;
     86 tag</a>.</p>
     87