1page.title=Defining Layouts 2 3@jd:body 4 5<div id="tb-wrapper"> 6<div id="tb"> 7<h2>This lesson teaches you to</h2> 8<ol> 9 <li><a href="#add-library">Add the Wearable UI Library</a></li> 10 <li><a href="#different-layouts">Specify Different Layouts for Square and Round Screens</a></li> 11 <li><a href="#same-layout">Use a Shape-Aware Layout</a></li> 12</ol> 13<h2>You should also read</h2> 14<ul> 15 <li><a href="{@docRoot}design/wear/index.html">Android Wear Design Principles</a></li> 16</ul> 17<h2>Video</h2> 18<ul> 19 <li><a href="https://www.youtube.com/watch?v=naf_WbtFAlY">Full Screen Apps for Android Wear</a></li> 20</ul> 21</div> 22</div> 23 24<p>Wearables use the same layout techniques as handheld Android devices, but need to be designed 25with specific constraints. Do not port functionality and the UI from a handheld app and expect a 26good experience. For more information on how to design great wearable apps, read the 27<a href="{@docRoot}design/wear/index.html">Android Wear Design Guidelines</a>.</p> 28 29<p>When you create layouts for Android Wear apps, you need to account for devices with square 30and round screens. Any content placed near the corners of the screen may be cropped on round 31Android Wear devices, so layouts designed for square screens do not work well on round devices. 32For a demonstration of this type of problem, see the video 33<a href="https://www.youtube.com/watch?v=naf_WbtFAlY">Full Screen Apps for Android Wear</a>.</p> 34 35<p>For example, figure 1 shows how the following layout looks on square and round screens:</p> 36 37<img src="{@docRoot}wear/images/01_uilib.png" alt="" width="500" height="261"/> 38<p class="img-caption"><strong>Figure 1.</strong> Demonstration of how a layout designed for 39square screens does not work well on round screens.</p> 40 41<pre> 42<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 43 xmlns:tools="http://schemas.android.com/tools" 44 android:layout_width="match_parent" 45 android:layout_height="match_parent" 46 android:orientation="vertical"> 47 48 <TextView 49 android:id="@+id/text" 50 android:layout_width="wrap_content" 51 android:layout_height="wrap_content" 52 android:text="@string/hello_square" /> 53</LinearLayout> 54</pre> 55 56<p>The text does not display correctly on devices with round screens.</p> 57 58<p>The Wearable UI Library provides two different approaches to solve this problem:</p> 59 60<ul> 61<li>Define different layouts for square and round devices. Your app detects the shape 62 of the device screen and inflates the correct layout at runtime.</li> 63<li>Use a special layout included in the library for both square and round devices. This layout 64 applies different window insets depending on the shape of the device screen.</li> 65</ul> 66 67<p>You typically use the first approach when you want your app to look different depending on 68the shape of the device screen. You use the second approach when you want to use a similar layout 69on both screen shapes without having views cropped near the edges of round screens.</p> 70 71 72<h2 id="add-library">Add the Wearable UI Library</h2> 73 74<p>Android Studio includes the Wearable UI Library on your <code>wear</code> module by default 75when you use the Project Wizard. To compile your project with this library, ensure that the 76<em>Extras</em> > <em>Google Repository</em> package is installed in 77the Android SDK manager and that the following dependency is included in the 78<code>build.gradle</code> file of your <code>wear</code> module:</p> 79 80<pre> 81dependencies { 82 compile fileTree(dir: 'libs', include: ['*.jar']) 83 <strong>compile 'com.google.android.support:wearable:+'</strong> 84 compile 'com.google.android.gms:play-services-wearable:+' 85} 86</pre> 87 88<p>The <code>'com.google.android.support:wearable'</code> dependency is required to implement 89the layout techniques shown in the following sections.</p> 90 91<p>Browse the <a href="{@docRoot}reference/android/support/wearable/view/package-summary.html"> 92API reference documentation</a> for the Wearable UI Library classes.</p> 93 94 95<h2 id="different-layouts">Specify Different Layouts for Square and Round Screens</h2> 96 97<p>The 98<a href="{@docRoot}reference/android/support/wearable/view/WatchViewStub.html"><code>WatchViewStub</code></a> 99class included in the Wearable UI Library lets you specify different layout definitions for square 100and round screens. This class detects the screen shape at runtime and inflates the corresponding 101layout.</p> 102 103<p>To use this class for handling different screen shapes in your app:</p> 104 105<ol> 106<li>Add 107<a href="{@docRoot}reference/android/support/wearable/view/WatchViewStub.html"><code>WatchViewStub</code></a> 108as the main element of your activity's layout.</li> 109<li>Specify a layout definition file for square screens with the <code>rectLayout</code> 110 attribute.</li> 111<li>Specify a layout definition file for round screens with the <code>roundLayout</code> 112 attribute.</li> 113</ol> 114 115<p>Define your activity's layout as follows:</p> 116 117<pre> 118<android.support.wearable.view.WatchViewStub 119 xmlns:android="http://schemas.android.com/apk/res/android" 120 xmlns:app="http://schemas.android.com/apk/res-auto" 121 xmlns:tools="http://schemas.android.com/tools" 122 android:id="@+id/watch_view_stub" 123 android:layout_width="match_parent" 124 android:layout_height="match_parent" 125 <strong>app:rectLayout="@layout/rect_activity_wear"</strong> 126 <strong>app:roundLayout="@layout/round_activity_wear"</strong>> 127</android.support.wearable.view.WatchViewStub> 128</pre> 129 130<p>Inflate this layout in your activity:</p> 131 132<pre> 133@Override 134protected void onCreate(Bundle savedInstanceState) { 135 super.onCreate(savedInstanceState); 136 setContentView(R.layout.activity_wear); 137} 138</pre> 139 140<p>Then create different layout definition files for square and round screens. In this example, 141you need to create the files <code>res/layout/rect_activity_wear.xml</code> and 142<code>res/layout/round_activity_wear.xml</code>. You define these layouts in the same way that 143you create layouts for handheld apps, but taking into account the constraints of wearable devices. 144The system inflates the correct layout at runtime depending on the screen shape.</p> 145 146<h3>Accessing layout views</h3> 147 148<p>The layouts that you specify for square or round screens are not inflated until 149<a href="{@docRoot}reference/android/support/wearable/view/WatchViewStub.html"><code>WatchViewStub</code></a> 150detects the shape of the screen, so your app cannot access their views 151immediately. To access these views, set a listener in your activity to be notified when 152the shape-specific layout has been inflated:</p> 153 154<pre> 155@Override 156protected void onCreate(Bundle savedInstanceState) { 157 super.onCreate(savedInstanceState); 158 setContentView(R.layout.activity_wear); 159 160 WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub); 161 stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() { 162 @Override public void onLayoutInflated(WatchViewStub stub) { 163 // Now you can access your views 164 TextView tv = (TextView) stub.findViewById(R.id.text); 165 ... 166 } 167 }); 168} 169</pre> 170 171 172<h2 id="same-layout">Use a Shape-Aware Layout</h2> 173 174<div style="float:right;margin-left:25px;width:260px"> 175<img src="{@docRoot}wear/images/02_uilib.png" width="250" height="250" alt=""/> 176<p class="img-caption"><strong>Figure 2.</strong> Window insets on a round screen.</p> 177</div> 178 179<p>The 180<a href="{@docRoot}reference/android/support/wearable/view/BoxInsetLayout.html"><code>BoxInsetLayout</code></a> 181class included in the Wearable UI Library extends 182{@link android.widget.FrameLayout} and lets you define a single layout that works for both square 183and round screens. This class applies the required window insets depending on the screen shape 184and lets you easily align views on the center or near the edges of the screen.</p> 185 186<p>The gray square in figure 2 shows the area where 187<a href="{@docRoot}reference/android/support/wearable/view/BoxInsetLayout.html"><code>BoxInsetLayout</code></a> 188can automatically place its child views on round screens after applying the required window insets. 189To be displayed inside this area, children views specify the <code>layout_box</code> atribute with 190these values: 191</p> 192 193<ul> 194<li>A combination of <code>top</code>, <code>bottom</code>, <code>left</code>, and 195 <code>right</code>. For example, <code>"left|top"</code> positions the child's left and top 196 edges inside the gray square in figure 2.</li> 197<li>The <code>all</code> value positions all the child's content inside the gray square in 198 figure 2.</li> 199</ul> 200 201<p>On square screens, the window insets are zero and the <code>layout_box</code> attribute is 202ignored.</p> 203 204<img src="{@docRoot}wear/images/03_uilib.png" width="500" height="253" alt=""/> 205<p class="img-caption"><strong>Figure 3.</strong> A layout definition that works on both 206square and round screens.</p> 207 208<p>The layout shown in figure 3 uses the 209<a href="{@docRoot}reference/android/support/wearable/view/BoxInsetLayout.html"><code><BoxInsetLayout></code></a> 210element and works on square and round screens:</p> 211 212<pre> 213<<strong>android.support.wearable.view.BoxInsetLayout</strong> 214 xmlns:android="http://schemas.android.com/apk/res/android" 215 xmlns:app="http://schemas.android.com/apk/res-auto" 216 <strong>android:background="@drawable/robot_background"</strong> 217 android:layout_height="match_parent" 218 android:layout_width="match_parent" 219 <strong>android:padding="15dp"</strong>> 220 221 <FrameLayout 222 android:layout_width="match_parent" 223 android:layout_height="match_parent" 224 <strong>android:padding="5dp"</strong> 225 <strong>app:layout_box="all"</strong>> 226 227 <TextView 228 android:gravity="center" 229 android:layout_height="wrap_content" 230 android:layout_width="match_parent" 231 android:text="@string/sometext" 232 android:textColor="@color/black" /> 233 234 <ImageButton 235 android:background="@null" 236 android:layout_gravity="bottom|left" 237 android:layout_height="50dp" 238 android:layout_width="50dp" 239 android:src="@drawable/ok" /> 240 241 <ImageButton 242 android:background="@null" 243 android:layout_gravity="bottom|right" 244 android:layout_height="50dp" 245 android:layout_width="50dp" 246 android:src="@drawable/cancel" /> 247 </FrameLayout> 248</android.support.wearable.view.BoxInsetLayout> 249</pre> 250 251<p>Notice the parts of the layout marked in bold:</p> 252 253<ul> 254<li> 255 <p><code>android:padding="15dp"</code></p> 256 <p>This line assigns padding to the 257 <a href="{@docRoot}reference/android/support/wearable/view/BoxInsetLayout.html"><code><BoxInsetLayout></code></a> 258 element. Because the window insets on round devices are larger than 15dp, this padding only 259 applies to square screens.</p> 260</li> 261<li> 262 <p><code>android:padding="5dp"</code></p> 263 <p>This line assigns padding to the inner {@link android.widget.FrameLayout} element. This padding 264 applies to both square and round screens. The total padding between the buttons and the window 265 insets is 20 dp on square screens (15+5) and 5 dp on round screens.</p> 266</li> 267<li> 268 <p><code>app:layout_box="all"</code></p> 269 <p>This line ensures that the {@link android.widget.FrameLayout} element and its children are 270 boxed inside the area defined by the window insets on round screens. This line has no effect on 271 square screens.</p> 272</li> 273</ul>