261 lines
11 KiB
Plaintext
261 lines
11 KiB
Plaintext
page.title=Defining Layouts
|
|
|
|
@jd:body
|
|
|
|
<div id="tb-wrapper">
|
|
<div id="tb">
|
|
<h2>This lesson teaches you to</h2>
|
|
<ol>
|
|
<li><a href="#add-library">Add the Wearable UI Library</a></li>
|
|
<li><a href="#different-layouts">Specify Different Layouts for Square and Round Screens</a></li>
|
|
<li><a href="#same-layout">Use a Shape-Aware Layout</a></li>
|
|
</ol>
|
|
<h2>You should also read</h2>
|
|
<ul>
|
|
<li><a href="{@docRoot}design/wear/index.html">Android Wear Design Principles</a></li>
|
|
</ul>
|
|
<h2>Video</h2>
|
|
<ul>
|
|
<li><a href="https://www.youtube.com/watch?v=naf_WbtFAlY">Full Screen Apps for Android Wear</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<p>Wearables use the same layout techniques as handheld Android devices, but need to be designed
|
|
with specific constraints. Do not port functionality and the UI from a handheld app and expect a
|
|
good experience. For more information on how to design great wearable apps, read the
|
|
<a href="{@docRoot}design/wear/index.html">Android Wear Design Guidelines</a>.</p>
|
|
|
|
<p>When you create layouts for Android Wear apps, you need to account for devices with square
|
|
and round screens. Any content placed near the corners of the screen may be cropped on round
|
|
Android Wear devices, so layouts designed for square screens do not work well on round devices.
|
|
For a demonstration of this type of problem, see the video
|
|
<a href="https://www.youtube.com/watch?v=naf_WbtFAlY">Full Screen Apps for Android Wear</a>.</p>
|
|
|
|
<p>For example, figure 1 shows how the following layout looks on square and round screens:</p>
|
|
|
|
<img src="{@docRoot}wear/images/01_uilib.png" alt="" width="500" height="261"/>
|
|
<p class="img-caption"><strong>Figure 1.</strong> Demonstration of how a layout designed for
|
|
square screens does not work well on round screens.</p>
|
|
|
|
<pre>
|
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
xmlns:tools="http://schemas.android.com/tools"
|
|
android:layout_width="match_parent"
|
|
android:layout_height="match_parent"
|
|
android:orientation="vertical">
|
|
|
|
<TextView
|
|
android:id="@+id/text"
|
|
android:layout_width="wrap_content"
|
|
android:layout_height="wrap_content"
|
|
android:text="@string/hello_square" />
|
|
</LinearLayout>
|
|
</pre>
|
|
|
|
<p>The text does not display correctly on devices with round screens.</p>
|
|
|
|
<p>The Wearable UI Library provides two different approaches to solve this problem:</p>
|
|
|
|
<ul>
|
|
<li>Define different layouts for square and round devices. Your app detects the shape
|
|
of the device screen and inflates the correct layout at runtime.</li>
|
|
<li>Use a special layout included in the library for both square and round devices. This layout
|
|
applies different window insets depending on the shape of the device screen.</li>
|
|
</ul>
|
|
|
|
<p>You typically use the first approach when you want your app to look different depending on
|
|
the shape of the device screen. You use the second approach when you want to use a similar layout
|
|
on both screen shapes without having views cropped near the edges of round screens.</p>
|
|
|
|
|
|
<h2 id="add-library">Add the Wearable UI Library</h2>
|
|
|
|
<p>Android Studio includes the Wearable UI Library on your <code>wear</code> module by default
|
|
when you use the Project Wizard. To compile your project with this library, ensure that the
|
|
<em>Extras</em> > <em>Google Repository</em> package is installed in
|
|
the Android SDK manager and that the following dependency is included in the
|
|
<code>build.gradle</code> file of your <code>wear</code> module:</p>
|
|
|
|
<pre>
|
|
dependencies {
|
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
|
<strong>compile 'com.google.android.support:wearable:+'</strong>
|
|
compile 'com.google.android.gms:play-services-wearable:+'
|
|
}
|
|
</pre>
|
|
|
|
<p>The <code>'com.google.android.support:wearable'</code> dependency is required to implement
|
|
the layout techniques shown in the following sections.</p>
|
|
|
|
<p>Browse the <a href="{@docRoot}reference/android/support/wearable/view/package-summary.html">
|
|
API reference documentation</a> for the Wearable UI Library classes.</p>
|
|
|
|
|
|
<h2 id="different-layouts">Specify Different Layouts for Square and Round Screens</h2>
|
|
|
|
<p>The <code>WatchViewStub</code> class included in the Wearable UI Library lets you specify
|
|
different layout definitions for square and round screens. This class detects the screen shape
|
|
at runtime and inflates the corresponding layout.</p>
|
|
|
|
<p>To use this class for handling different screen shapes in your app:</p>
|
|
|
|
<ol>
|
|
<li>Add <code>WatchViewStub</code> as the main element of your activity's layout.</li>
|
|
<li>Specify a layout definition file for square screens with the <code>rectLayout</code>
|
|
attribute.</li>
|
|
<li>Specify a layout definition file for round screens with the <code>roundLayout</code>
|
|
attribute.</li>
|
|
</ol>
|
|
|
|
<p>Define your activity's layout as follows:</p>
|
|
|
|
<pre>
|
|
<android.support.wearable.view.WatchViewStub
|
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
xmlns:tools="http://schemas.android.com/tools"
|
|
android:id="@+id/watch_view_stub"
|
|
android:layout_width="match_parent"
|
|
android:layout_height="match_parent"
|
|
<strong>app:rectLayout="@layout/rect_activity_wear"</strong>
|
|
<strong>app:roundLayout="@layout/round_activity_wear"</strong>>
|
|
</android.support.wearable.view.WatchViewStub>
|
|
</pre>
|
|
|
|
<p>Inflate this layout in your activity:</p>
|
|
|
|
<pre>
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.activity_wear);
|
|
}
|
|
</pre>
|
|
|
|
<p>Then create different layout definition files for square and round screens. In this example,
|
|
you need to create the files <code>res/layout/rect_activity_wear.xml</code> and
|
|
<code>res/layout/round_activity_wear.xml</code>. You define these layouts in the same way that
|
|
you create layouts for handheld apps, but taking into account the constraints of wearable devices.
|
|
The system inflates the correct layout at runtime depending on the screen shape.</p>
|
|
|
|
<h3>Accessing layout views</h3>
|
|
|
|
<p>The layouts that you specify for square or round screens are not inflated until
|
|
<code>WatchViewStub</code> detects the shape of the screen, so your app cannot access their views
|
|
immediately. To access these views, set a listener in your activity to be notified when
|
|
the shape-specific layout has been inflated:</p>
|
|
|
|
<pre>
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.activity_wear);
|
|
|
|
WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
|
|
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
|
|
@Override public void onLayoutInflated(WatchViewStub stub) {
|
|
// Now you can access your views
|
|
TextView tv = (TextView) stub.findViewById(R.id.text);
|
|
...
|
|
}
|
|
});
|
|
}
|
|
</pre>
|
|
|
|
|
|
<h2 id="same-layout">Use a Shape-Aware Layout</h2>
|
|
|
|
<div style="float:right;margin-left:25px;width:260px">
|
|
<img src="{@docRoot}wear/images/02_uilib.png" width="250" height="250" alt=""/>
|
|
<p class="img-caption"><strong>Figure 2.</strong> Window insets on a round screen.</p>
|
|
</div>
|
|
|
|
<p>The <code>BoxInsetLayout</code> class included in the Wearable UI Library extends
|
|
{@link android.widget.FrameLayout} and lets you define a single layout that works for both square
|
|
and round screens. This class applies the required window insets depending on the screen shape
|
|
and lets you easily align views on the center or near the edges of the screen.</p>
|
|
|
|
<p>The gray square in figure 2 shows the area where <code>BoxInsetLayout</code> can automatically
|
|
place its child views on round screens after applying the required window insets. To be displayed
|
|
inside this area, children views specify the <code>layout_box</code> atribute with these values:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>A combination of <code>top</code>, <code>bottom</code>, <code>left</code>, and
|
|
<code>right</code>. For example, <code>"left|top"</code> positions the child's left and top
|
|
edges inside the gray square in figure 2.</li>
|
|
<li>The <code>all</code> value positions all the child's content inside the gray square in
|
|
figure 2.</li>
|
|
</ul>
|
|
|
|
<p>On square screens, the window insets are zero and the <code>layout_box</code> attribute is
|
|
ignored.</p>
|
|
|
|
<img src="{@docRoot}wear/images/03_uilib.png" width="500" height="253" alt=""/>
|
|
<p class="img-caption"><strong>Figure 3.</strong> A layout definition that works on both
|
|
square and round screens.</p>
|
|
|
|
<p>The layout shown in figure 3 uses <code>BoxInsetLayout</code> and works on square and
|
|
round screens:</p>
|
|
|
|
<pre>
|
|
<<strong>android.support.wearable.view.BoxInsetLayout</strong>
|
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
<strong>android:background="@drawable/robot_background"</strong>
|
|
android:layout_height="match_parent"
|
|
android:layout_width="match_parent"
|
|
<strong>android:padding="15dp"</strong>>
|
|
|
|
<FrameLayout
|
|
android:layout_width="match_parent"
|
|
android:layout_height="match_parent"
|
|
<strong>android:padding="5dp"</strong>
|
|
<strong>app:layout_box="all"</strong>>
|
|
|
|
<TextView
|
|
android:gravity="center"
|
|
android:layout_height="wrap_content"
|
|
android:layout_width="match_parent"
|
|
android:text="@string/sometext"
|
|
android:textColor="@color/black" />
|
|
|
|
<ImageButton
|
|
android:background="@null"
|
|
android:layout_gravity="bottom|left"
|
|
android:layout_height="50dp"
|
|
android:layout_width="50dp"
|
|
android:src="@drawable/ok" />
|
|
|
|
<ImageButton
|
|
android:background="@null"
|
|
android:layout_gravity="bottom|right"
|
|
android:layout_height="50dp"
|
|
android:layout_width="50dp"
|
|
android:src="@drawable/cancel" />
|
|
</FrameLayout>
|
|
</android.support.wearable.view.BoxInsetLayout>
|
|
</pre>
|
|
|
|
<p>Notice the parts of the layout marked in bold:</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<p><code>android:padding="15dp"</code></p>
|
|
<p>This line assigns padding to the <code>BoxInsetLayout</code> element. Because the window
|
|
insets on round devices are larger than 15dp, this padding only applies to square screens.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>android:padding="5dp"</code></p>
|
|
<p>This line assigns padding to the inner <code>FrameLayout</code> element. This padding applies
|
|
to both square and round screens. The total padding between the buttons and the window insets
|
|
is 20 dp on square screens (15+5) and 5 dp on round screens.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>app:layout_box="all"</code></p>
|
|
<p>This line ensures that the <code>FrameLayout</code> element and its children are boxed inside
|
|
the area defined by the window insets on round screens. This line has no effect on square
|
|
screens.</p>
|
|
</li>
|
|
</ul> |