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