• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Layout Tricks: Creating Efficient Layouts
2parent.title=Articles
3parent.link=../browser.html?tag=article
4@jd:body
5
6<p>The Android UI toolkit offers several layout managers that are
7rather easy to use and, most of the time, you only need the basic
8features of these layout managers to implement a user interface.</p>
9
10<p>Sticking to the basic features is unfortunately not the most efficient
11way to create user interfaces. A common example is the abuse of
12{@link android.widget.LinearLayout}, which leads to a proliferation of
13views in the view hierarchy. Every view &mdash; or worse, every layout
14manager &mdash; that you add to your application comes at a cost:
15initialization, layout and drawing become slower. The layout pass can be
16especially expensive when you nest several <code>LinearLayout</code>
17that use the {@link android.R.attr#layout_weight weight}
18parameter, which requires the child to be measured twice.</p>
19
20<p>Let's consider a very simple and common example of a layout: a list item
21with an icon on the left, a title at the top and an optional description
22underneath the title. Here is what such an item looks like:</p>
23
24<div style="text-align: center;"><img src="images/relativelayout_1.png" alt="Simple list item"></div>
25
26<p>To clearly understand how the views, one {@link android.widget.ImageView} and
27two {@link android.widget.TextView}, are positioned with respect to each other,
28here is the wireframe of the layout as captured by <a
29href="{@docRoot}guide/developing/tools/hierarchy-viewer.html">HierarchyViewer</a
30>:</p>
31
32<div style="text-align: center;"><img src="images/relativelayout_wire_1.png" alt="Wireframe of the simple list item"></div>
33
34<p>Implementing this layout is straightforward with <code>LinearLayout</code>.
35The item itself is a horizontal <code>LinearLayout</code> with an
36<code>ImageView</code> and a vertical <code>LinearLayout</code>, which contains
37the two <code>TextView</code>. Here's the source code of this layout:</p>
38
39<pre class="prettyprint">&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
40    android:layout_width="fill_parent"
41    android:layout_height="?android:attr/listPreferredItemHeight"
42
43    android:padding="6dip"&gt;
44
45    &lt;ImageView
46        android:id="&#64;+id/icon"
47
48        android:layout_width="wrap_content"
49        android:layout_height="fill_parent"
50        android:layout_marginRight="6dip"
51
52        android:src="&#64;drawable/icon" /&gt;
53
54    &lt;LinearLayout
55        android:orientation="vertical"
56
57        android:layout_width="0dip"
58        android:layout_weight="1"
59        android:layout_height="fill_parent"&gt;
60
61        &lt;TextView
62            android:layout_width="fill_parent"
63            android:layout_height="0dip"
64            android:layout_weight="1"
65
66            android:gravity="center_vertical"
67            android:text="My Application" /&gt;
68
69        &lt;TextView
70            android:layout_width="fill_parent"
71            android:layout_height="0dip"
72            android:layout_weight="1"
73
74            android:singleLine="true"
75            android:ellipsize="marquee"
76            android:text="Simple application that shows how to use RelativeLayout" /&gt;
77
78    &lt;/LinearLayout&gt;
79
80&lt;/LinearLayout&gt;</pre>
81
82<p>This layout works but can be wasteful if you instantiate it for every list
83item of a {@link android.widget.ListView}. The same layout can be rewritten
84using a single {@link android.widget.RelativeLayout}, thus saving one view, and
85even better one level in view hierarchy, per list item. The implementation of
86the layout with a <code>RelativeLayout</code> remains simple:</p>
87
88<pre class="prettyprint">&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
89    android:layout_width="fill_parent"
90    android:layout_height="?android:attr/listPreferredItemHeight"
91
92    android:padding="6dip"&gt;
93
94    &lt;ImageView
95        android:id="&#64;+id/icon"
96
97        android:layout_width="wrap_content"
98        android:layout_height="fill_parent"
99
100        android:layout_alignParentTop="true"
101        android:layout_alignParentBottom="true"
102        android:layout_marginRight="6dip"
103
104        android:src="&#64;drawable/icon" /&gt;
105
106    &lt;TextView
107        android:id="&#64;+id/secondLine"
108
109        android:layout_width="fill_parent"
110        android:layout_height="26dip"
111
112        android:layout_toRightOf="&#64;id/icon"
113        android:layout_alignParentBottom="true"
114        android:layout_alignParentRight="true"
115
116        android:singleLine="true"
117        android:ellipsize="marquee"
118        android:text="Simple application that shows how to use RelativeLayout" /&gt;
119
120    &lt;TextView
121        android:layout_width="fill_parent"
122        android:layout_height="wrap_content"
123
124        android:layout_toRightOf="&#64;id/icon"
125        android:layout_alignParentRight="true"
126        android:layout_alignParentTop="true"
127        android:layout_above="&#64;id/secondLine"
128        android:layout_alignWithParentIfMissing="true"
129
130        android:gravity="center_vertical"
131        android:text="My Application" /&gt;
132
133&lt;/RelativeLayout&gt;</pre>
134
135<p>This new implementation behaves exactly the same way as the previous
136implementation, except in one case. The list item we want to display has two
137lines of text: the title and an <em>optional</em> description. When a
138description is not available for a given list item, the application would simply
139set the visibility of the second <code>TextView</code> to
140{@link android.view.View#GONE}. This works perfectly with the <code>LinearLayout</code>
141implementation but not with the <code>RelativeLayout</code> version:</p>
142
143<div style="text-align: center;"><img src="images/relativelayout_2.png" alt="RelativeLayout and description GONE"></div>
144<div style="text-align: center;"><img src="images/relativelayout_wire_2.png" alt="RelativeLayout and description GONE"></div>
145
146<p>In a <code>RelativeLayout</code>, views are aligned with their parent, with the
147<code>RelativeLayout</code> itself, or with other views. For instance, we declared that
148the description is aligned with the bottom of the <code>RelativeLayout</code> and
149that the title is positioned above the description and anchored to the
150parent's top. With the description GONE, RelativeLayout doesn't know
151where to position the title's bottom edge. To solve this problem, you
152can use a very special layout parameter called
153{@link android.R.attr#layout_alignWithParentIfMissing}.
154</p>
155
156<p>This boolean parameter simply tells RelativeLayout to use its own edges as
157anchors when a constraint target is missing. For instance, if you position a
158view to the right of a GONE view and set <code>alignWithParentIfMissing</code>
159to <code>true</code>, <code>RelativeLayout</code> will instead anchor the view
160to its left edge. In our case, using <code>alignWithParentIfMissing</code> will
161cause <code>RelativeLayout</code> to align the title's bottom with its own
162bottom. The result is the following:</p>
163
164<div style="text-align: center;"><img src="images/relativelayout_3.png" alt="RelativeLayout, description GONE and alignWithParentIfMissing"></div>
165<div style="text-align: center;"><img src="images/relativelayout_wire_3.png" alt="RelativeLayout, description GONE and alignWithParentIfMissing"></div>
166
167<p>The
168behavior of our layout is now perfect, even when the description is
169GONE. Even better, the hierarchy is simpler and because we are not
170using LinearLayout's weights it's also more efficient. The difference
171between the two implementations becomes obvious when comparing the view
172hierarchies in HierarchyViewer:</p>
173
174<div style="text-align: center;"><img src="images/layouts_comparison_small.png" alt="LinearLayout vs RelativeLayout"></div>
175
176<p>Again, the difference will be much more important when you use such a layout
177for every item in a ListView for instance. Hopefully this simple
178example showed you that getting to know your layouts is the best way to
179learn how to optimize your UI.</p>
180