85 lines
4.4 KiB
Plaintext
85 lines
4.4 KiB
Plaintext
|
page.title=Layout Tricks: Using ViewStubs
|
||
|
@jd:body
|
||
|
|
||
|
<p>Sharing and reusing UI components is very easy with Android, thanks to the <a
|
||
|
href="layout-tricks-reuse.html"><include /></a> tag. Sometimes it's so
|
||
|
easy to create complex UI constructs that your UI ends up with a large number of
|
||
|
views, some of which are rarely used. Thankfully, Android offers a very special
|
||
|
widget called {@link android.view.ViewStub}, which brings you all the benefits
|
||
|
of the <code><include /></code> without polluting your user interface with
|
||
|
rarely used views.</p>
|
||
|
|
||
|
<p>A <code>ViewStub</code> is a dumb and lightweight view. It has no dimension,
|
||
|
it does not draw anything and does not participate in the layout in any way.
|
||
|
This means that a <code>ViewStub</code> is very cheap to inflate and very cheap
|
||
|
to keep in a view hierarchy. A <code>ViewStub</code> can be best described as a
|
||
|
<em>lazy include</em>. The layout referenced by a <code>ViewStub</code> is
|
||
|
inflated and added to the user interface only when you decide so.</p>
|
||
|
|
||
|
<p>The following screenshot comes from the <a
|
||
|
href="http://code.google.com/p/shelves">Shelves</a> application. The main purpose of
|
||
|
the activity shown in the screenshot is to present the user with a browsable
|
||
|
list of books:</p>
|
||
|
|
||
|
<img style="margin: 0px auto 10px; display: block; text-align: center;" src="images/viewstub1.png" alt="" id="BLOGGER_PHOTO_ID_5314039375336055346" border="0">
|
||
|
|
||
|
<p>The same activity is also used when the user adds or imports new books.
|
||
|
During such an operation, Shelves shows extra bits of user interface.
|
||
|
The screenshot below shows the progress bar and cancel button that
|
||
|
appear at the bottom of the screen during an import:</p>
|
||
|
|
||
|
<img style="margin: 0px auto 10px; display: block; text-align: center;" src="images/viewstub2.png" alt="" id="BLOGGER_PHOTO_ID_5314039800002559378" border="0">
|
||
|
|
||
|
<p>Because importing books is not a common operation, at least when compared to
|
||
|
browsing the list of books, the import panel is originally represented
|
||
|
by a <code>ViewStub</code>:</p>
|
||
|
|
||
|
<img style="margin: 0px auto 10px; display: block; text-align: center;" src="images/viewstub3.png" alt="" id="BLOGGER_PHOTO_ID_5314040334008167378" border="0">
|
||
|
|
||
|
<p>When the user initiates the import process, the <code>ViewStub</code> is
|
||
|
inflated and replaced by the content of the layout file it references:</p>
|
||
|
|
||
|
<img style="margin: 0px auto 10px; display: block; text-align: center;" src="images/viewstub4.png" alt="" id="BLOGGER_PHOTO_ID_5314040638747834450" border="0">
|
||
|
|
||
|
<p>To use a <code>ViewStub</code>, all you need is to specify an
|
||
|
<code>android:id</code> attribute, to later inflate the stub, and an
|
||
|
<code>android:layout</code> attribute, to reference what layout file
|
||
|
to include and inflate. A stub lets you use a third attribute,
|
||
|
<code>android:inflatedId</code>, which can be used to override the
|
||
|
<code>id</code> of the root of the included file. Finally, the layout
|
||
|
parameters specified on the stub will be applied to the roof of the
|
||
|
included layout. Here is an example:</p>
|
||
|
|
||
|
<pre class="prettyprint"><ViewStub
|
||
|
android:id="@+id/stub_import"
|
||
|
android:inflatedId="@+id/panel_import"
|
||
|
|
||
|
android:layout="@layout/progress_overlay"
|
||
|
|
||
|
android:layout_width="fill_parent"
|
||
|
android:layout_height="wrap_content"
|
||
|
android:layout_gravity="bottom" /></pre>
|
||
|
|
||
|
<p>When you are ready to inflate the stub, simply invoke the
|
||
|
{@link android.view.ViewStub#inflate()} method. You can also simply change the
|
||
|
visibility of the stub to {@link android.view.View#VISIBLE} or
|
||
|
{@link android.view.View#INVISIBLE} and the stub will inflate. Note however that the
|
||
|
<code>inflate()</code> method has the benefit of returning the root
|
||
|
<code>View</code> of the inflate layout:</p>
|
||
|
|
||
|
<pre class="prettyprint">((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
|
||
|
// or
|
||
|
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();</pre>
|
||
|
|
||
|
<p>It is very important to remember that after the stub is inflated, the stub is
|
||
|
<em>removed</em> from the view hierarchy. As such, it is unnecessary to keep a
|
||
|
long-lived reference, for instance in an class instance field, to a
|
||
|
<code>ViewStub</code>.</p>
|
||
|
|
||
|
<p>A <code>ViewStub</code> is a great compromise between ease of programming and
|
||
|
efficiency. Instead of inflating views manually and adding them at runtime to
|
||
|
your view hierarchy, simply use a <code>ViewStub</code>. It's cheap and easy.
|
||
|
The only drawback of <code>ViewStub</code> is that it currently does
|
||
|
<em>not</em> support the <a href="layout-tricks-merge.html"><merge />
|
||
|
tag</a>.</p>
|