diff options
Diffstat (limited to 'docs/html/preview/tv/ui/layouts.jd')
-rw-r--r-- | docs/html/preview/tv/ui/layouts.jd | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/docs/html/preview/tv/ui/layouts.jd b/docs/html/preview/tv/ui/layouts.jd new file mode 100644 index 0000000..0659826 --- /dev/null +++ b/docs/html/preview/tv/ui/layouts.jd @@ -0,0 +1,298 @@ +page.title=Layouts for TV + +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>In this document</h2> + <ol> + <li><a href="#themes">Themes</a> + <ol> + <li><a href="#leanback-theme">Leanback Theme</a></li> + <li><a href="#notitle-theme">NoTitleBar Theme</a></li> + </ol> + </li> + <li><a href="#structure">Layout Structure</a> + <ol> + <li><a href="#overscan">Overscan</a></li> + </ol> + </li> + <li><a href="#visibility">Text and Controls Visibility</a></li> + <li><a href="#density-resources">Screen Density and Image Resources</a></li> + <li><a href="#anti-patterns">Layout Anti-Patterns</a></li> + <li><a href="#large-bitmaps">Handling Large Bitmaps</a></li> + </ol> + +</div> +</div> + +<p> + A TV screen is typically viewed from about 10 feet away, and while it is much larger than most + other Android device displays, this type of screen does not provide the same level of precise + detail and color as a smaller device. These factors require that you create app layouts with + TV devices in mind in order to create a useful and enjoyable user experience.</p> + +<p>This guide provides direction and implementation details for building effective layouts inN + TV apps.</p> + + +<h2 id="themes">Themes</h2> + +<p>Android <a href="{@docRoot}guide/topics/ui/themes.html">Themes</a> can provide a basis for + layouts in your TV apps. You should use a theme to modify the display of your app activities + that are meant to run on a TV device. This section explains which themes you should use.</p> + + +<h3 id="leanback-theme">Leanback Theme</h3> + +<p>The Leanback library provides a standard theme for TV activities, called {@code + Leanback.Theme}, which establishes a consistent visual style for TV apps. Use of this theme is + recommended for most apps. This theme is recommended for any TV app that uses the Leanback + library classes. The following code sample shows how to apply this theme to a given + activity within an app:</p> + +<pre> +<activity + android:name="com.example.android.TvActivity" + android:label="@string/app_name" + <strong>android:theme="@style/Theme.Leanback"</strong>> +</pre> + + +<h3 id="notitle-theme">NoTitleBar Theme</h3> + +<p>The title bar is a standard user interface element for Android apps on phones and tablets, + but it is not appropriate for TV apps. If you are not using the Leanback library classes, + you should apply this theme to your TV activities. The following code example from a TV app + manifest demonstrates how to apply this theme to remove the display of a title bar: +</p> + +<pre> +<application> + ... + + <activity + android:name="com.example.android.TvActivity" + android:label="@string/app_name" + <strong>android:theme="@android:style/Theme.NoTitleBar"</strong>> + ... + + </activity> +</application> +</pre> + + +<h2 id="structure">Layout Structure</h2> + +<p>Layouts for TV devices should follow some basic guidelines to ensure they are usable and + effective on large screens. Follow these tips to build landscape layouts optimized for TV screens: +</p> + +<ul> + <li>Build layouts with a landscape orientation. TV screens always display in landscape.</li> + <li>Put on-screen navigation controls on the left or right side of the screen and save the + vertical space for content.</li> + <li>Create UIs that are divided into sections, using <a + href="{@docRoot}guide/components/fragments.html" + >Fragments</a>, and use view groups like {@link android.widget.GridView} instead of {@link + android.widget.ListView} to make better use of the horizontal screen space. + </li> + <li>Use view groups such as {@link android.widget.RelativeLayout} or {@link + android.widget.LinearLayout} to arrange views. This approach allows the system to adjust the + position of the views to the size, alignment, aspect ratio, and pixel density of a TV screen.</li> + <li>Add sufficient margins between layout controls to avoid a cluttered UI.</li> +</ul> + + +<h3 id="overscan">Overscan</h3> + +<p>Layouts for TV have some unique requirements due to the evolution of TV standards and the + desire to always present a full screen picture to viewers. For this reason, TV devices may + clip the outside edge of an app layout in order to ensure that the entire display is filled. + This behavior is generally referred to as Overscan.</p> + +<p>In order to account for the impact of overscan and make sure that all the user interface + elements you place in a layout are actually shown on screen, you should incorporate a 10% margin + on all sides of your layout. This translates into a 27dp margin on the left and right edges and + a 48dp margin on the top and bottom of your base layouts for activities. The following + example layout demonstrates how to set these margins in the root layout for a TV app: +</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/base_layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:layout_marginTop="27dp" + android:layout_marginLeft="48dp" + android:layout_marginRight="48dp" + android:layout_marginBottom="27dp" > +</LinearLayout> +</pre> + +<p class="caution"> + <strong>Caution:</strong> Do not apply overscan margins to your layout if you are using the + Leanback Support Library {@code BrowseFragment} or related widgets, as those layouts already + incorporate overscan-safe margins. +</p> + + +<h2 id="visibility">Text and Controls Visibility</h2> + +<p> +The text and controls in a TV app layout should be easily visible and navigable from a distance. +Follow these tips to make them easier to see from a distance : +</p> + +<ul> + <li>Break text into small chunks that users can quickly scan.</li> + <li>Use light text on a dark background. This style is easier to read on a TV.</li> + <li>Avoid lightweight fonts or fonts that have both very narrow and very broad strokes. + Use simple sans-serif fonts and anti-aliasing to increase readability.</li> + <li>Use Android's standard font sizes: +<pre> +<TextView + android:id="@+id/atext" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceMedium"/> +</pre> + </li> + <li>Ensure that all your view widgets are large enough to be clearly visible to someone + sitting 10 feet away from the screen (this distance is greater for very large screens). The + best way to do this is to use layout-relative sizing rather than absolute sizing, and + density-independent pixel units instead of absolute pixel units. For example, to set the + width of a widget, use wrap_content instead of a pixel measurement, and to set the margin + for a widget, use dip instead of px values.</li> +</ul> + + +<h2 id="density-resources">Screen Density and Image Resources</h2> + +<p>The common high-definition TV display resolutions are 720p, 1080i, and 1080p. + Your TV layout should target a screen size of 1920 x 1080 pixels, and then allow the Android + system to downscale your layout elements to 720p if necessary. In general, downscaling + (removing pixels) does not degrade your layout presentation quality. However, upscaling can + cause display artifacts that degrade the quality of your layout and have a negative impact on + the user experience of your app.</p> + +<p> + To get the best scaling results for images, provide them as + <a href="{@docRoot}tools/help/draw9patch.html">9-patch image</a> elements if possible. If you + provide low quality or small images in your layouts, they will appear pixelated, fuzzy, or + grainy. This is not a good experience for the user. Instead, use high-quality images. +</p> + +<p> + For more information on optimizing layouts and resources for large screens see + <a href="{@docRoot}training/multiscreen/index.html">Designing for multiple screens</a>. +</p> + + +<h2 id="anti-patterns">Layout Anti-Patterns</h2> + +<p>There are a few approaches to building layouts for TV that you should avoid because they do not +work well and lead to bad user experiences. Here are some user interface approaches you +should specifically <em>not</em> use when developing a layout for TV. +</p> + +<ul> + <li><strong>Re-using phone or tablet layouts</strong> - Do not reuse layouts from a phone or + tablet app without modification. Layouts built for other Android device form factors are not + well suited for TV devices and should be simplified for operation on a TV.</li> + <li><strong>ActionBar</strong> - While this user interface convention is recommended for use + on phones and tablets, it is not appropriate for a TV interface. In particular, using an + action bar options menu (or any pull-down menu for that matter) is strongly discouraged, due + to the difficulty in navigating such a menu with a remote control.</li> + <li><strong>ViewPager</strong> - Sliding between screens can work great on a phone or tablet, + but don't try this on a TV!</li> + +</ul> + +<p>For more information on designing layouts that are appropriate to TV, see the + <a href="{@docRoot}design/tv/index.html">TV Design</a> guide.</p> + + +<h2 id="large-bitmaps">Handling Large Bitmaps</h2> + +<p>TV devices, like any other Android device, have a limited amount of memory. If you build your + app layout with very high-resolution images or use many high-resolution images in the operation + of your app, it can quickly run into memory limits and cause out of memory errors. + To avoid these types of problems, follow these tips:</p> + +<ul> + <li>Load images only when they're displayed on the screen. For example, when displaying multiple images in + a {@link android.widget.GridView} or + {@link android.widget.Gallery}, only load an image when + {@link android.widget.Adapter#getView(int, View, ViewGroup) getView()} + is called on the View's {@link android.widget.Adapter}. + </li> + <li>Call {@link android.graphics.Bitmap#recycle()} on + {@link android.graphics.Bitmap} views that are no longer needed. + </li> + <li>Use {@link java.lang.ref.WeakReference} for storing references + to {@link android.graphics.Bitmap} objects in an in-memory + {@link java.util.Collection}.</li> + <li>If you fetch images from the network, use {@link android.os.AsyncTask} + to fetch and store them on the device for faster access. + Never do network transactions on the application's UI thread. + </li> + <li>Scale down large images to a more appropriate size as you download them; + otherwise, downloading the image itself may cause an out of memory exception. + The following sample code demonstrates how to scale down images while downloading: +<pre> + // Get the source image's dimensions + BitmapFactory.Options options = new BitmapFactory.Options(); + // This does not download the actual image, just downloads headers. + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(IMAGE_FILE_URL, options); + // The actual width of the image. + int srcWidth = options.outWidth; + // The actual height of the image. + int srcHeight = options.outHeight; + + // Only scale if the source is bigger than the width of the destination view. + if(desiredWidth > srcWidth) + desiredWidth = srcWidth; + + // Calculate the correct inSampleSize/scale value. This approach helps reduce + // memory use. This value should be a power of 2. + int inSampleSize = 1; + while(srcWidth / 2 > desiredWidth){ + srcWidth /= 2; + srcHeight /= 2; + inSampleSize *= 2; + } + + float desiredScale = (float) desiredWidth / srcWidth; + + // Decode with inSampleSize + options.inJustDecodeBounds = false; + options.inDither = false; + options.inSampleSize = inSampleSize; + options.inScaled = false; + // Ensures the image stays as a 32-bit ARGB_8888 image. + // This preserves image quality. + options.inPreferredConfig = Bitmap.Config.ARGB_8888; + + Bitmap sampledSrcBitmap = BitmapFactory.decodeFile(IMAGE_FILE_URL, options); + + // Resize + Matrix matrix = new Matrix(); + matrix.postScale(desiredScale, desiredScale); + Bitmap scaledBitmap = Bitmap.createBitmap(sampledSrcBitmap, 0, 0, + sampledSrcBitmap.getWidth(), sampledSrcBitmap.getHeight(), matrix, true); + sampledSrcBitmap = null; + + // Save + FileOutputStream out = new FileOutputStream(LOCAL_PATH_TO_STORE_IMAGE); + scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); + scaledBitmap = null; +</pre> + </li> +</ul> + |