Skip to content

Commit 2474814

Browse files
Megha JoshiAndroid Git Automerger
authored andcommitted
am 43562ec: Merge "Creating new "Optimizing for TV" training." into ics-mr1
* commit '43562ecf434092308765e2c31377c46612ba61bb': Creating new "Optimizing for TV" training.
2 parents e371ed8 + 43562ec commit 2474814

File tree

7 files changed

+680
-0
lines changed

7 files changed

+680
-0
lines changed
30.9 KB
Loading
144 KB
Loading

docs/html/resources/resources_toc.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,26 @@
278278
</a>
279279
</li>
280280
</ul>
281+
</li>
282+
<li class="toggle-list">
283+
<div><a href="<?cs var:toroot ?>training/tv/index.html">
284+
<span class="en">Designing for TV<span class="new">&nbsp;new!</span></span>
285+
</a>
286+
</div>
287+
<ul>
288+
<li><a href="<?cs var:toroot ?>training/tv/optimizing-layouts-tv.html">
289+
<span class="en">Optimizing Layouts for TV</span>
290+
</a>
291+
</li>
292+
<li><a href="<?cs var:toroot ?>training/tv/optimizing-navigation-tv.html">
293+
<span class="en">Optimizing Navigation for TV</span>
294+
</a>
295+
</li>
296+
<li><a href="<?cs var:toroot ?>training/tv/unsupported-features-tv.html">
297+
<span class="en">Handling Features Not Supported on TV</span>
298+
</a>
299+
</li>
300+
</ul>
281301
</li>
282302

283303
<li class="toggle-list">

docs/html/training/tv/index.jd

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
page.title=Designing for TV
2+
3+
trainingnavtop=true
4+
startpage=true
5+
next.title=Optimizing layouts for TV
6+
next.link=optimizing-layouts-tv.html
7+
8+
@jd:body
9+
10+
<div id="tb-wrapper">
11+
<div id="tb">
12+
13+
<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
14+
<h2>Dependencies and prerequisites</h2>
15+
<ul>
16+
<li>Android 2.0 (API Level 5) or higher</li>
17+
</ul>
18+
19+
</div>
20+
</div>
21+
<p>
22+
Smart TVs powered by Android bring your favorite Android apps to the best screen in your house.
23+
Thousands of apps in the Google Play Store are already optimized for TVs. This class shows how
24+
you can optimize your Android app for TVs, including how to build a layout that
25+
works great when the user is ten feet away and navigating with a remote control.
26+
</p>
27+
28+
<h2>Lessons</h2>
29+
30+
<dl>
31+
<dt><b><a href="optimizing-layouts-tv.html">Optimizing Layouts for TV</a></b></dt>
32+
<dd>Shows you how to optimize app layouts for TV screens, which have some unique characteristics such as:
33+
<ul>
34+
<li>permanent "landscape" mode</li>
35+
<li>high-resolution displays</li>
36+
<li>"10 foot UI" environment.</li>
37+
</ul>
38+
</dd>
39+
40+
<dt><b><a href="optimizing-navigation-tv.html">Optimizing Navigation for TV</a></b></dt>
41+
<dd>Shows you how to design navigation for TVs, including:
42+
<ul>
43+
<li>handling D-pad navigation</li>
44+
<li>providing navigational feedback</li>
45+
<li>providing easily-accessible controls on the screen.</li>
46+
</ul>
47+
</dd>
48+
49+
<dt><b><a href="unsupported-features-tv.html">Handling features not supported on TV</a></b></dt>
50+
<dd>Lists the hardware features that are usually not available on TVs. This lesson also shows you how to
51+
provide alternatives for missing features or check for missing features and disable code at run time.</dd>
52+
</dl>
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
page.title=Optimizing Layouts for TV
2+
parent.title=Designing for TV
3+
parent.link=index.html
4+
5+
trainingnavtop=true
6+
next.title=Optimizing Navigation for TV
7+
next.link=optimizing-navigation-tv.html
8+
9+
@jd:body
10+
11+
<div id="tb-wrapper">
12+
<div id="tb">
13+
14+
<h2>This lesson teaches you to</h2>
15+
<ol>
16+
<li><a href="#DesignLandscapeLayouts">Design Landscape Layouts</a></li>
17+
<li><a href="#MakeTextControlsEasyToSee">Make Text and Controls Easy to See</a></li>
18+
<li><a href="#DesignForLargeScreens">Design for High-Density Large Screens</a></li>
19+
<li><a href="#HandleLargeBitmaps">Handle Large Bitmaps in Your Application</a></li>
20+
</ol>
21+
22+
<h2>You should also read</h2>
23+
<ul>
24+
<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
25+
</ul>
26+
27+
</div>
28+
</div>
29+
30+
<p>
31+
When your application is running on a television set, you should assume that the user is sitting about
32+
ten feet away from the screen. This user environment is referred to as the
33+
<a href="http://en.wikipedia.org/wiki/10-foot_user_interface">10-foot UI</a>. To provide your
34+
users with a usable and enjoyable experience, you should style and lay out your UI accordingly..
35+
</p>
36+
<p>
37+
This lesson shows you how to optimize layouts for TV by:
38+
</p>
39+
<ul>
40+
<li>Providing appropriate layout resources for landscape mode.</li>
41+
<li>Ensuring that text and controls are large enough to be visible from a distance.</li>
42+
<li>Providing high resolution bitmaps and icons for HD TV screens.</li>
43+
</ul>
44+
45+
<h2 id="DesignLandscapeLayouts">Design Landscape Layouts</h2>
46+
47+
<p>
48+
TV screens are always in landscape orientation. Follow these tips to build landscape layouts optimized for TV screens:
49+
</p>
50+
<ul>
51+
<li>Put on-screen navigational controls on the left or right side of the screen and save the
52+
vertical space for content.</li>
53+
<li>Create UIs that are divided into sections, by using <a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a>
54+
and use view groups like {@link android.widget.GridView} instead
55+
of {@link android.widget.ListView} to make better use of the
56+
horizontal screen space.</li>
57+
<li>Use view groups such as {@link android.widget.RelativeLayout}
58+
or {@link android.widget.LinearLayout} to arrange views.
59+
This allows the Android system to adjust the position of the views to the size, alignment,
60+
aspect ratio, and pixel density of the TV screen.</li>
61+
<li>Add sufficient margins between layout controls to avoid a cluttered UI.</li>
62+
</ul>
63+
64+
<p>
65+
For example, the following layout is optimized for TV:
66+
</p>
67+
68+
<img src="{@docRoot}images/training/panoramio-grid.png" />
69+
70+
<p>
71+
In this layout, the controls are on the lefthand side. The UI is displayed within a
72+
{@link android.widget.GridView}, which is well-suited to landscape orientation.
73+
In this layout both GridView and Fragment have the width and height set
74+
dynamically, so they can adjust to the screen resolution. Controls are added to the left side Fragment programatically at runtime.
75+
The layout file for this UI is {@code res/layout-land-large/photogrid_tv.xml}.
76+
(This layout file is placed in {@code layout-land-large} because TVs have large screens with landscape orientation. For details refer to
77+
<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.)</p>
78+
79+
res/layout-land-large/photogrid_tv.xml
80+
<pre>
81+
&lt;RelativeLayout
82+
android:layout_width="fill_parent"
83+
android:layout_height="fill_parent" &gt;
84+
85+
&lt;fragment
86+
android:id="@+id/leftsidecontrols"
87+
android:layout_width="0dip"
88+
android:layout_marginLeft="5dip"
89+
android:layout_height="match_parent" /&gt;
90+
91+
&lt;GridView
92+
android:id="@+id/gridview"
93+
android:layout_width="wrap_content"
94+
android:layout_height="wrap_content" /&gt;
95+
96+
&lt;/RelativeLayout>
97+
</pre>
98+
99+
<p>
100+
To set up action bar items on the left side of the screen, you can also include the <a
101+
href="http://code.google.com/p/googletv-android-samples/source/browse/#git%2FLeftNavBarLibrary">
102+
Left navigation bar library</a> in your application to set up action items on the left side
103+
of the screen, instead of creating a custom Fragment to add controls:
104+
</p>
105+
106+
<pre>
107+
LeftNavBar bar = (LeftNavBarService.instance()).getLeftNavBar(this);
108+
</pre>
109+
110+
<p>
111+
When you have an activity in which the content scrolls vertically, always use a left navigation bar;
112+
otherwise, your users have to scroll to the top of the content to switch between the content view and
113+
the ActionBar. Look at the
114+
<a href="http://code.google.com/p/googletv-android-samples/source/browse/#git%2FLeftNavBarDemo">
115+
Left navigation bar sample app</a> to see how to simple it is to include the left navigation bar in your app.
116+
</p>
117+
118+
<h2 id="MakeTextControlsEasyToSee">Make Text and Controls Easy to See</h2>
119+
<p>
120+
The text and controls in a TV application's UI should be easily visible and navigable from a distance.
121+
Follow these tips to make them easier to see from a distance :
122+
</p>
123+
124+
<ul>
125+
<li>Break text into small chunks that users can quickly scan.</li>
126+
<li>Use light text on a dark background. This style is easier to read on a TV.</li>
127+
<li>Avoid lightweight fonts or fonts that have both very narrow and very broad strokes. Use simple sans-serif
128+
fonts and use anti-aliasing to increase readability.</li>
129+
<li>Use Android's standard font sizes:
130+
<pre>
131+
&lt;TextView
132+
android:id="@+id/atext"
133+
android:layout_width="wrap_content"
134+
android:layout_height="wrap_content"
135+
android:gravity="center_vertical"
136+
android:singleLine="true"
137+
android:textAppearance="?android:attr/textAppearanceMedium"/&gt;
138+
</pre></li>
139+
<li>Ensure that all your view widgets are large enough to be clearly visible to someone sitting 10 feet away
140+
from the screen (this distance is greater for very large screens). The best way to do this is to use
141+
layout-relative sizing rather than absolute sizing, and density-independent pixel units instead of absolute
142+
pixel units. For example, to set the width of a widget, use wrap_content instead of a pixel measurement,
143+
and to set the margin for a widget, use dip instead of px values.
144+
</li>
145+
</ul>
146+
<p>
147+
148+
</p>
149+
150+
<h2 id="DesignForLargeScreens">Design for High-Density Large Screens</h2>
151+
152+
<p>
153+
The common HDTV display resolutions are 720p, 1080i, and 1080p. Design your UI for 1080p, and then
154+
allow the Android system to downscale your UI to 720p if necessary. In general, downscaling (removing pixels)
155+
does not degrade the UI (Notice that the converse is not true; you should avoid upscaling because it degrades
156+
UI quality).
157+
</p>
158+
159+
<p>
160+
To get the best scaling results for images, provide them as <a href="{@docRoot}guide/developing/tools/draw9patch.html">
161+
9-patch image</a> elements if possible.
162+
If you provide low quality or small images in your layouts, they will appear pixelated, fuzzy, or grainy. This
163+
is not a good experience for the user. Instead, use high-quality images.
164+
</p>
165+
166+
<p>
167+
For more information on optimizing apps for large screens see <a href="{@docRoot}training/multiscreen/index.html">
168+
Designing for multiple screens</a>.
169+
</p>
170+
171+
<h2 id="HandleLargeBitmaps">Design to Handle Large Bitmaps</h2>
172+
173+
<p>
174+
The Android system has a limited amount of memory, so downloading and storing high-resolution images can often
175+
cause out-of-memory errors in your app. To avoid this, follow these tips:
176+
</p>
177+
178+
<ul>
179+
<li>Load images only when they're displayed on the screen. For example, when displaying multiple images in
180+
a {@link android.widget.GridView} or
181+
{@link android.widget.Gallery}, only load an image when
182+
{@link android.widget.Adapter#getView(int, View, ViewGroup) getView()}
183+
is called on the View's {@link android.widget.Adapter}.
184+
</li>
185+
<li>Call {@link android.graphics.Bitmap#recycle()} on
186+
{@link android.graphics.Bitmap} views that are no longer needed.
187+
</li>
188+
<li>Use {@link java.lang.ref.WeakReference} for storing references
189+
to {@link android.graphics.Bitmap} objects in a in-memory
190+
<a href="{@link java.util.Collection}.</li>
191+
<li>If you fetch images from the network, use {@link android.os.AsyncTask}
192+
to fetch them and store them on the SD card for faster access.
193+
Never do network transactions on the application's UI thread.
194+
</li>
195+
<li>Scale down really large images to a more appropriate size as you download them; otherwise, downloading the image
196+
itself may cause an "Out of Memory" exception. Here is sample code that scales down images while downloading:
197+
198+
<pre>
199+
// Get the source image's dimensions
200+
BitmapFactory.Options options = new BitmapFactory.Options();
201+
// This does not download the actual image, just downloads headers.
202+
options.inJustDecodeBounds = true;
203+
BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
204+
// The actual width of the image.
205+
int srcWidth = options.outWidth;
206+
// The actual height of the image.
207+
int srcHeight = options.outHeight;
208+
209+
// Only scale if the source is bigger than the width of the destination view.
210+
if(desiredWidth > srcWidth)
211+
desiredWidth = srcWidth;
212+
213+
// Calculate the correct inSampleSize/scale value. This helps reduce memory use. It should be a power of 2.
214+
int inSampleSize = 1;
215+
while(srcWidth / 2 > desiredWidth){
216+
srcWidth /= 2;
217+
srcHeight /= 2;
218+
inSampleSize *= 2;
219+
}
220+
221+
float desiredScale = (float) desiredWidth / srcWidth;
222+
223+
// Decode with inSampleSize
224+
options.inJustDecodeBounds = false;
225+
options.inDither = false;
226+
options.inSampleSize = inSampleSize;
227+
options.inScaled = false;
228+
// Ensures the image stays as a 32-bit ARGB_8888 image.
229+
// This preserves image quality.
230+
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
231+
232+
Bitmap sampledSrcBitmap = BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
233+
234+
// Resize
235+
Matrix matrix = new Matrix();
236+
matrix.postScale(desiredScale, desiredScale);
237+
Bitmap scaledBitmap = Bitmap.createBitmap(sampledSrcBitmap, 0, 0,
238+
sampledSrcBitmap.getWidth(), sampledSrcBitmap.getHeight(), matrix, true);
239+
sampledSrcBitmap = null;
240+
241+
// Save
242+
FileOutputStream out = new FileOutputStream(LOCAL_PATH_TO_STORE_IMAGE);
243+
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
244+
scaledBitmap = null;
245+
</pre>
246+
</li> </ul>

0 commit comments

Comments
 (0)