summaryrefslogtreecommitdiffstats
path: root/docs/html/training
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/training')
-rw-r--r--docs/html/training/articles/perf-tips.jd2
-rw-r--r--docs/html/training/material/animations.jd548
-rw-r--r--docs/html/training/material/compatibility.jd172
-rw-r--r--docs/html/training/material/drawables.jd119
-rw-r--r--docs/html/training/material/get-started.jd173
-rw-r--r--docs/html/training/material/images/RecyclerView.pngbin0 -> 39757 bytes
-rw-r--r--docs/html/training/material/images/SceneTransition.pngbin0 -> 214713 bytes
-rw-r--r--docs/html/training/material/images/ThemeColors.pngbin0 -> 62879 bytes
-rw-r--r--docs/html/training/material/images/shadows-depth.pngbin0 -> 18031 bytes
-rw-r--r--docs/html/training/material/index.jd62
-rw-r--r--docs/html/training/material/lists-cards.jd266
-rw-r--r--docs/html/training/material/shadows-clipping.jd127
-rw-r--r--docs/html/training/material/theme.jd131
-rw-r--r--docs/html/training/training_toc.cs158
-rw-r--r--docs/html/training/tv/discovery/in-app-search.jd145
-rw-r--r--docs/html/training/tv/discovery/index.jd48
-rw-r--r--docs/html/training/tv/discovery/recommendations.jd240
-rw-r--r--docs/html/training/tv/games/index.jd282
-rw-r--r--docs/html/training/tv/index.jd57
-rw-r--r--docs/html/training/tv/optimizing-layouts-tv.jd246
-rw-r--r--docs/html/training/tv/optimizing-navigation-tv.jd206
-rw-r--r--docs/html/training/tv/playback/browse.jd230
-rw-r--r--docs/html/training/tv/playback/details.jd247
-rw-r--r--docs/html/training/tv/playback/index.jd52
-rw-r--r--docs/html/training/tv/playback/now-playing.jd167
-rw-r--r--docs/html/training/tv/start/hardware.jd361
-rw-r--r--docs/html/training/tv/start/index.jd63
-rw-r--r--docs/html/training/tv/start/layouts.jd257
-rw-r--r--docs/html/training/tv/start/navigation.jd180
-rw-r--r--docs/html/training/tv/start/start.jd259
-rw-r--r--docs/html/training/tv/tif/index.jd48
-rw-r--r--docs/html/training/tv/unsupported-features-tv.jd157
-rw-r--r--docs/html/training/wearables/apps/layouts.jd2
-rw-r--r--docs/html/training/wearables/notifications/creating.jd2
34 files changed, 4317 insertions, 690 deletions
diff --git a/docs/html/training/articles/perf-tips.jd b/docs/html/training/articles/perf-tips.jd
index 1660b7f..e9df51b 100644
--- a/docs/html/training/articles/perf-tips.jd
+++ b/docs/html/training/articles/perf-tips.jd
@@ -388,7 +388,7 @@ was 2x slower; the actual difference was more like 6% slower. Furthermore,
the JIT makes the two effectively indistinguishable.</p>
<p>On devices without a JIT, caching field accesses is about 20% faster than
-repeatedly accesssing the field. With a JIT, field access costs about the same
+repeatedly accessing the field. With a JIT, field access costs about the same
as local access, so this isn't a worthwhile optimization unless you feel it
makes your code easier to read. (This is true of final, static, and static
final fields too.)
diff --git a/docs/html/training/material/animations.jd b/docs/html/training/material/animations.jd
new file mode 100644
index 0000000..e8291b8
--- /dev/null
+++ b/docs/html/training/material/animations.jd
@@ -0,0 +1,548 @@
+page.title=Defining Custom Animations
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#Touch">Customize Touch Feedback</a></li>
+ <li><a href="#Reveal">Use the Reveal Effect</a></li>
+ <li><a href="#Transitions">Customize Activity Transitions</a></li>
+ <li><a href="#ViewState">Animate View State Changes</a></li>
+ <li><a href="#AnimVector">Animate Vector Drawables</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">Material design specification</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Material design on Android</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>Animations in material design give users feedback on their actions and provide visual
+continuity as users interact with your app. The material theme provides some default animations
+for buttons and activity transitions, and Android 5.0 (API level 21) and above lets you customize
+these animations and create new ones:</p>
+
+<ul>
+<li>Touch feedback</li>
+<li>Circular Reveal</li>
+<li>Activity transitions</li>
+<li>Curved motion</li>
+<li>View state changes</li>
+</ul>
+
+
+<h2 id="Touch">Customize Touch Feedback</h2>
+
+<p>Touch feedback in material design provides an instantaneous visual confirmation at the
+point of contact when users interact with UI elements. The default touch feedback animations
+for buttons use the new {@link android.graphics.drawable.RippleDrawable} class, which transitions
+between different states with a ripple effect.</p>
+
+<p>In most cases, you should apply this functionality in your view XML by specifying the view
+background as:</p>
+
+<ul>
+<li><code>?android:attr/selectableItemBackground</code> for a bounded ripple</li>
+<li><code>?android:attr/selectableItemBackgroundBorderless</code> for a ripple that extends beyond
+the view</li>
+</ul>
+
+<p class="note"><strong>Note:</strong> <code>selectableItemBackgroundBorderless</code> is a new
+attribute introduced in API level 21.</p>
+
+
+<p>Alternatively, you can define a {@link android.graphics.drawable.RippleDrawable}
+as an XML resource using the <code>ripple</code> element.</p>
+
+<p>You can assign a color to {@link android.graphics.drawable.RippleDrawable} objects. To change
+the default touch feedback color, use the theme's <code>android:colorControlHighlight</code>
+attribute.</p>
+
+<p>For more information, see the API reference for the {@link
+android.graphics.drawable.RippleDrawable} class.</p>
+
+
+<h2 id="Reveal">Use the Reveal Effect</h2>
+
+<p>Reveal animations provide users visual continuity when you show or hide a group of UI
+elements. The {@link android.view.ViewAnimationUtils#createCircularReveal
+ViewAnimationUtils.createCircularReveal()} method enables you to animate a clipping circle to
+reveal or hide a view.</p>
+
+<p>To reveal a previously invisible view using this effect:</p>
+
+<pre>
+// previously invisible view
+View myView = findViewById(R.id.my_view);
+
+// get the center for the clipping circle
+int cx = (myView.getLeft() + myView.getRight()) / 2;
+int cy = (myView.getTop() + myView.getBottom()) / 2;
+
+// get the final radius for the clipping circle
+int finalRadius = myView.getWidth();
+
+// create and start the animator for this view
+// (the start radius is zero)
+Animator anim =
+ ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
+anim.start();
+</pre>
+
+<p>To hide a previously visible view using this effect:</p>
+
+<pre>
+// previously visible view
+final View myView = findViewById(R.id.my_view);
+
+// get the center for the clipping circle
+int cx = (myView.getLeft() + myView.getRight()) / 2;
+int cy = (myView.getTop() + myView.getBottom()) / 2;
+
+// get the initial radius for the clipping circle
+int initialRadius = myView.getWidth();
+
+// create the animation (the final radius is zero)
+Animator anim =
+ ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);
+
+// make the view invisible when the animation is done
+anim.addListener(new AnimatorListenerAdapter() {
+ &#64;Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ myView.setVisibility(View.INVISIBLE);
+ }
+});
+
+// start the animation
+anim.start();
+</pre>
+
+
+<h2 id="Transitions">Customize Activity Transitions</h2>
+
+<!-- shared transition video -->
+<div style="width:290px;margin-left:35px;float:right">
+ <div class="framed-nexus5-port-span-5">
+ <video class="play-on-hover" autoplay="">
+ <source src="{@docRoot}design/material/videos/ContactsAnim.mp4">
+ <source src="{@docRoot}design/material/videos/ContactsAnim.webm">
+ <source src="{@docRoot}design/material/videos/ContactsAnim.ogv">
+ </video>
+ </div>
+ <div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
+ <p class="img-caption" style="margin-top:3px;margin-bottom:10px"><strong>Figure 1</strong> - A
+ transition with shared elements.</p>
+ <em>To replay the movie, click on the device screen</em>
+ </div>
+</div>
+
+<p>Activity transitions in material design apps provide visual connections between different states
+through motion and transformations between common elements. You can specify custom animations for
+enter and exit transitions and for transitions of shared elements between activities.</p>
+
+<ul>
+<li>An <strong>enter</strong> transition determines how views in an activity enter the scene.
+For example, in the <em>explode</em> enter transition, the views enter the scene from the outside
+and fly in towards the center of the screen.</li>
+
+<li>An <strong>exit</strong> transition determines how views in an activity exit the scene. For
+ example, in the <em>explode</em> exit transition, the views exit the scene away from the
+center.</li>
+
+<li>A <strong>shared elements</strong> transition determines how views that are shared between
+two activities transition between these activities. For example, if two activities have the same
+image in different positions and sizes, the <em>changeImageTransform</em> shared element transition
+translates and scales the image smoothly between these activities.</li>
+</ul>
+
+<p>Android 5.0 (API level 21) supports these enter and exit transitions:</p>
+
+<ul>
+<li><em>explode</em> - Moves views in or out from the center of the scene.</li>
+<li><em>slide</em> - Moves views in or out from one of the edges of the scene.</li>
+<li><em>fade</em> - Adds or removes a view from the scene by changing its opacity.</li>
+</ul>
+
+<p>Any transition that extends the {@link android.transition.Visibility} class is supported
+as an enter or exit transition. For more information, see the API reference for the
+{@link android.transition.Transition} class.</p>
+
+<p>Android 5.0 (API level 21) also supports these shared elements transitions:</p>
+
+<ul>
+<li><em>changeBounds</em> - Animates the changes in layout bounds of target views.</li>
+<li><em>changeClipBounds</em> - Animates the changes in clip bounds of target views.</li>
+<li><em>changeTransform</em> - Animates the changes in scale and rotation of target views.</li>
+<li><em>changeImageTransform</em> - Animates changes in size and scale of target images.</li>
+</ul>
+
+<p>When you enable activity transitions in your app, the default cross-fading transition is
+activated between the entering and exiting activities.</p>
+
+<img src="{@docRoot}training/material/images/SceneTransition.png" alt="" width="600" height="405"
+ style="margin-top:20px"/>
+<p class="img-caption">
+  <strong>Figure 2</strong> - A scene transition with one shared element.
+</p>
+
+<h3>Specify custom transitions</h3>
+
+<p>First, enable window content transitions with the <code>android:windowContentTransitions</code>
+attribute when you define a style that inherits from the material theme. You can also specify
+enter, exit, and shared element transitions in your style definition:</p>
+
+<pre>
+&lt;style name="BaseAppTheme" parent="android:Theme.Material">
+ &lt;!-- enable window content transitions -->
+ &lt;item name="android:windowContentTransitions">true&lt;/item>
+
+ &lt;!-- specify enter and exit transitions -->
+ &lt;item name="android:windowEnterTransition">@transition/explode&lt;/item>
+ &lt;item name="android:windowExitTransition">@transition/explode&lt;/item>
+
+ &lt;!-- specify shared element transitions -->
+ &lt;item name="android:windowSharedElementEnterTransition">
+ &#64;transition/change_image_transform&lt;/item>
+ &lt;item name="android:windowSharedElementExitTransition">
+ &#64;transition/change_image_transform&lt;/item>
+&lt;/style>
+</pre>
+
+<p>The <code>change_image_transform</code> transition in this example is defined as follows:</p>
+
+<pre>
+&lt;!-- res/transition/change_image_transform.xml -->
+&lt;!-- (see also Shared Transitions below) -->
+&lt;transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;changeImageTransform/>
+&lt;/transitionSet>
+</pre>
+
+<p>The <code>changeImageTransform</code> element corresponds to the
+{@link android.transition.ChangeImageTransform} class. For more information, see the API
+reference for {@link android.transition.Transition}.</p>
+
+<p>To enable window content transitions in your code instead, call the
+{@link android.view.Window#requestFeature Window.requestFeature()} method:</p>
+
+<pre>
+// inside your activity (if you did not enable transitions in your theme)
+getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
+
+// set an exit transition
+getWindow().setExitTransition(new Explode());
+</pre>
+
+<p>To specify transitions in your code, call these methods with a {@link
+android.transition.Transition} object:</p>
+
+<ul>
+ <li>{@link android.view.Window#setEnterTransition Window.setEnterTransition()}</li>
+ <li>{@link android.view.Window#setExitTransition Window.setExitTransition()}</li>
+ <li>{@link android.view.Window#setSharedElementEnterTransition
+ Window.setSharedElementEnterTransition()}</li>
+ <li>{@link android.view.Window#setSharedElementExitTransition
+ Window.setSharedElementExitTransition()}</li>
+</ul>
+
+<p>The {@link android.view.Window#setExitTransition setExitTransition()} and {@link
+android.view.Window#setSharedElementExitTransition setSharedElementExitTransition()} methods define
+the exit transition for the calling activity. The {@link android.view.Window#setEnterTransition
+setEnterTransition()} and {@link android.view.Window#setSharedElementEnterTransition
+setSharedElementEnterTransition()} methods define the enter transition for the called activity.</p>
+
+<p>To get the full effect of a transition, you must enable window content transitions on both the
+calling and called activities. Otherwise, the calling activity will start the exit transition,
+but then you'll see a window transition (like scale or fade).</p>
+
+<p>To start an enter transition as soon as possible, use the
+{@link android.view.Window#setAllowEnterTransitionOverlap Window.setAllowEnterTransitionOverlap()}
+method on the called activity. This lets you have more dramatic enter transitions.</p>
+
+<h3>Start an activity using transitions</h3>
+
+<p>If you enable transitions and set an exit transition for an activity, the transition is activated
+when you launch another activity as follows:</p>
+
+<pre>
+startActivity(intent,
+ ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
+</pre>
+
+<p>If you have set an enter transition for the second activity, the transition is also activated
+when the activity starts. To disable transitions when you start another activity, provide
+a <code>null</code> options bundle.</p>
+
+<h3>Start an activity with a shared element</h3>
+
+<p>To make a screen transition animation between two activities that have a shared element:</p>
+
+<ol>
+<li>Enable window content transitions in your theme.</li>
+<li>Specify a shared elements transition in your style.</li>
+<li>Define your transition as an XML resource.</li>
+<li>Assign a common name to the shared elements in both layouts with the
+ <code>android:transitionName</code> attribute.</li>
+<li>Use the {@link android.app.ActivityOptions#makeSceneTransitionAnimation
+ActivityOptions.makeSceneTransitionAnimation()} method.</li>
+</ol>
+
+<pre>
+// get the element that receives the click event
+final View imgContainerView = findViewById(R.id.img_container);
+
+// get the common element for the transition in this activity
+final View androidRobotView = findViewById(R.id.image_small);
+
+// define a click listener
+imgContainerView.setOnClickListener(new View.OnClickListener() {
+ &#64;Override
+ public void onClick(View view) {
+ Intent intent = new Intent(this, Activity2.class);
+ // create the transition animation - the images in the layouts
+ // of both activities are defined with android:transitionName="robot"
+ ActivityOptions options = ActivityOptions
+ .makeSceneTransitionAnimation(this, androidRobotView, "robot");
+ // start the new activity
+ startActivity(intent, options.toBundle());
+ }
+});
+</pre>
+
+<p>For shared dynamic views that you generate in your code, use the
+{@link android.view.View#setTransitionName View.setTransitionName()} method to specify a common
+element name in both activities.</p>
+
+<p>To reverse the scene transition animation when you finish the second activity, call the
+{@link android.app.Activity#finishAfterTransition Activity.finishAfterTransition()}
+method instead of {@link android.app.Activity#finish Activity.finish()}.</p>
+
+<h3>Start an activity with multiple shared elements</h3>
+
+<p>To make a scene transition animation between two activities that have more than one shared
+element, define the shared elements in both layouts with the <code>android:transitionName</code>
+attribute (or use the {@link android.view.View#setTransitionName View.setTransitionName()} method
+in both activities), and create an {@link android.app.ActivityOptions} object as follows:</p>
+
+<pre>
+ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
+ Pair.create(view1, "agreedName1"),
+ Pair.create(view2, "agreedName2"));
+</pre>
+
+
+<h2 id="CurvedMotion">Use Curved Motion</h2>
+
+<p>Animations in material design rely on curves for time interpolation and spatial movement
+patterns. With Android 5.0 (API level 21) and above, you can define custom timing curves and
+curved motion patterns for animations.</p>
+
+<p>The {@link android.view.animation.PathInterpolator} class is a new interpolator based on a
+Bézier curve or a {@link android.graphics.Path} object. This interpolator specifies a motion curve
+in a 1x1 square, with anchor points at (0,0) and (1,1) and control points as specified using the
+constructor arguments. You can also define a path interpolator as an XML resource:</p>
+
+<pre>
+&lt;pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:controlX1="0.4"
+ android:controlY1="0"
+ android:controlX2="1"
+ android:controlY2="1"/>
+</pre>
+
+<p>The system provides XML resources for the three basic curves in the material design
+specification:</p>
+
+<ul>
+ <li><code>&#64;interpolator/fast_out_linear_in.xml</code></li>
+ <li><code>&#64;interpolator/fast_out_slow_in.xml</code></li>
+ <li><code>&#64;interpolator/linear_out_slow_in.xml</code></li>
+</ul>
+
+<p>You can pass a {@link android.view.animation.PathInterpolator} object to the {@link
+android.animation.Animator#setInterpolator Animator.setInterpolator()} method.</p>
+
+<p>The {@link android.animation.ObjectAnimator} class has new constructors that enable you to animate
+coordinates along a path using two or more properties at once. For example, the following animator
+uses a {@link android.graphics.Path} object to animate the X and Y properties of a view:</p>
+
+<pre>
+ObjectAnimator mAnimator;
+mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
+...
+mAnimator.start();
+</pre>
+
+
+<h2 id="ViewState">Animate View State Changes</h2>
+
+<p>The {@link android.animation.StateListAnimator} class lets you define animators that run when
+the state of a view changes. The following example shows how to define an {@link
+android.animation.StateListAnimator} as an XML resource:</p>
+
+<pre>
+&lt;!-- animate the translationZ property of a view when pressed -->
+&lt;selector xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;item android:state_pressed="true">
+ &lt;set>
+ &lt;objectAnimator android:propertyName="translationZ"
+ android:duration="@android:integer/config_shortAnimTime"
+ android:valueTo="2dp"
+ android:valueType="floatType"/>
+ &lt;!-- you could have other objectAnimator elements
+ here for "x" and "y", or other properties -->
+ &lt;/set>
+ &lt;/item>
+ &lt;item android:state_enabled="true"
+ android:state_pressed="false"
+ android:state_focused="true">
+ &lt;set>
+ &lt;objectAnimator android:propertyName="translationZ"
+ android:duration="100"
+ android:valueTo="0"
+ android:valueType="floatType"/>
+ &lt;/set>
+ &lt;/item>
+&lt;/selector>
+</pre>
+
+<p>To attach custom view state animations to a view, define an animator using the
+<code>selector</code> element in an XML resource file as in this example, and assign it to your
+view with the <code>android:stateListAnimator</code> attribute. To assign a state list animator
+to a view in your code, use the {@link android.animation.AnimatorInflater#loadStateListAnimator
+AnimationInflater.loadStateListAnimator()} method, and assign the animator to your view with the
+{@link android.view.View#setStateListAnimator View.setStateListAnimator()} method.</p>
+
+<p>When your theme extends the material theme, buttons have a Z animation by default. To avoid this
+behavior in your buttons, set the <code>android:stateListAnimator</code> attribute to
+<code>@null</code>.</p>
+
+<p>The {@link android.graphics.drawable.AnimatedStateListDrawable} class lets you create drawables
+that show animations between state changes of the associated view. Some of the system widgets in
+Android 5.0 use these animations by default. The following example shows how
+to define an {@link android.graphics.drawable.AnimatedStateListDrawable} as an XML resource:</p>
+
+<pre>
+&lt;!-- res/drawable/myanimstatedrawable.xml -->
+&lt;animated-selector
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ &lt;!-- provide a different drawable for each state-->
+ &lt;item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
+ android:state_pressed="true"/>
+ &lt;item android:id="@+id/focused" android:drawable="@drawable/drawableF"
+ android:state_focused="true"/>
+ &lt;item android:id="@id/default"
+ android:drawable="@drawable/drawableD"/>
+
+ &lt;!-- specify a transition -->
+ &lt;transition android:fromId="@+id/default" android:toId="@+id/pressed">
+ &lt;animation-list>
+ &lt;item android:duration="15" android:drawable="@drawable/dt1"/>
+ &lt;item android:duration="15" android:drawable="@drawable/dt2"/>
+ ...
+ &lt;/animation-list>
+ &lt;/transition>
+ ...
+&lt;/animated-selector>
+</pre>
+
+
+<h2 id="AnimVector">Animate Vector Drawables</h2>
+
+<p><a href="{@docRoot}training/material/drawables.html#VectorDrawables">Vector Drawables</a> are
+scalable without losing definition. The {@link android.graphics.drawable.AnimatedVectorDrawable}
+class lets you animate the properties of a vector drawable.</p>
+
+<p>You normally define animated vector drawables in three XML files:</p>
+
+<ul>
+<li>A vector drawable with the <code>&lt;vector&gt;</code> element in
+<code>res/drawable/</code></li>
+<li>An animated vector drawable with the <code>&lt;animated-vector&gt;</code> element in
+<code>res/drawable/</code></li>
+<li>One or more object animators with the <code>&lt;objectAnimator&gt;</code> element in
+<code>res/anim/</code></li>
+</ul>
+
+<p>Animated vector drawables can animate the attributes of the <code>&lt;group&gt;</code> and
+<code>&lt;path&gt;</code> elements. The <code>&lt;group&gt;</code> elements defines a set of
+paths or subgroups, and the <code>&lt;path&gt;</code> element defines paths to be drawn.</p>
+
+<p>When you define a vector drawable that you want to animate, use the <code>android:name</code>
+attribute to assign a unique name to groups and paths, so you can refer to them from your animator
+definitions. For example:</p>
+
+<pre>
+&lt;!-- res/drawable/vectordrawable.xml -->
+&lt;vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="64dp"
+ android:width="64dp"
+ android:viewportHeight="600"
+ android:viewportWidth="600">
+ &lt;group
+ <strong>android:name="rotationGroup"</strong>
+ android:pivotX="300.0"
+ android:pivotY="300.0"
+ android:rotation="45.0" >
+ &lt;path
+ <strong>android:name="v"</strong>
+ android:fillColor="#000000"
+ android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
+ &lt;/group>
+&lt;/vector>
+</pre>
+
+<p>The animated vector drawable definition refers to the groups and paths in the vector drawable
+by their names:</p>
+
+<pre>
+&lt;!-- res/drawable/animvectordrawable.xml -->
+&lt;animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/vectordrawable" >
+ &lt;target
+ android:name="rotationGroup"
+ android:animation="@anim/rotation" />
+ &lt;target
+ android:name="v"
+ android:animation="@anim/path_morph" />
+&lt;/animated-vector>
+</pre>
+
+<p>The animation definitions represent {@link android.animation.ObjectAnimator} or {@link
+android.animation.AnimatorSet} objects. The first animator in this example rotates the target
+group 360 degrees:</p>
+
+<pre>
+&lt;!-- res/anim/rotation.xml -->
+&lt;objectAnimator
+ android:duration="6000"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="360" />
+</pre>
+
+<p>The second animator in this example morphs the vector drawable's path from one shape to
+another. Both paths must be compatible for morphing: they must have the same number of commands
+and the same number of parameters for each command.</p>
+
+<pre>
+&lt;!-- res/anim/path_morph.xml -->
+&lt;set xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;objectAnimator
+ android:duration="3000"
+ android:propertyName="pathData"
+ android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z"
+ android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z"
+ android:valueType="pathType" />
+&lt;/set>
+</pre>
+
+<p>For more information, see the API reference for {@link
+android.graphics.drawable.AnimatedVectorDrawable}.</p>
diff --git a/docs/html/training/material/compatibility.jd b/docs/html/training/material/compatibility.jd
new file mode 100644
index 0000000..5e03450
--- /dev/null
+++ b/docs/html/training/material/compatibility.jd
@@ -0,0 +1,172 @@
+page.title=Maintaining Compatibility
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#Theme">Define Alternative Styles</a></li>
+ <li><a href="#Layouts">Provide Alternative Layouts</a></li>
+ <li><a href="#SupportLib">Use the Support Library</a></li>
+ <li><a href="#CheckVersion">Check the System Version</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">Material design specification</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Material design on Android</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>Some material design features like the material theme and custom activity transitions are
+only available on Android 5.0 (API level 21) and above. However, you can design your apps to make
+use of these features when running on devices that support material design and still be compatible
+with devices running previous releases of Android.</p>
+
+
+<h2 id="Theme">Define Alternative Styles</h2>
+
+<p>You can configure your app to use the material theme on devices that support it and revert
+to an older theme on devices running earlier versions of Android:</p>
+
+<ol>
+<li>Define a theme that inherits from an older theme (like Holo) in
+ <code>res/values/styles.xml</code>.</li>
+<li>Define a theme with the same name that inherits from the material theme in
+ <code>res/values-v21/styles.xml</code>.</li>
+<li>Set this theme as your app's theme in the manifest file.</li>
+</ol>
+
+<p class="note"><strong>Note:</strong>
+If your app uses the material theme but does not provide an alternative theme in this manner,
+your app will not run on versions of Android earlier than 5.0.
+</p>
+
+
+<h2 id="Layouts">Provide Alternative Layouts</h2>
+
+<p>If the layouts that you design according to the material design guidelines do not use any of
+the new XML attributes introduced in Android 5.0 (API level 21), they will work on previous
+versions of Android. Otherwise, you can provide alternative layouts. You can also provide
+alternative layouts to customize how your app looks on earlier versions of Android.</p>
+
+<p>Create your layout files for Android 5.0 (API level 21) inside <code>res/layout-v21/</code> and
+your alternative layout files for earlier versions of Android inside <code>res/layout/</code>.
+For example, <code>res/layout/my_activity.xml</code> is an alternative layout for
+<code>res/layout-v21/my_activity.xml</code>.</p>
+
+<p>To avoid duplication of code, define your styles inside <code>res/values/</code>, modify the
+styles in <code>res/values-v21/</code> for the new APIs, and use style inheritance, defining base
+styles in <code>res/values/</code> and inheriting from those in <code>res/values-v21/</code>.</p>
+
+
+<h2 id="SupportLib">Use the Support Library</h2>
+
+<p>The <a href="{@docRoot}tools/support-library/features.html#v7">v7 Support Libraries</a>
+r21 and above includes the following material design features:</p>
+
+<ul>
+<li><a href="{@docRoot}training/material/theme.html">Material design styles</a> for some system
+ widgets when you apply one of the <code>Theme.AppCompat</code> themes.</li>
+<li><a href="{@docRoot}training/material/theme.html#ColorPalette">Color palette theme attributes</a>
+ in the <code>Theme.AppCompat</code> themes.</li>
+<li>The {@link android.support.v7.widget.RecyclerView} widget to <a
+ href="{@docRoot}training/material/lists-cards.html#RecyclerView">display data
+ collections</a>.</li>
+<li>The {@link android.support.v7.widget.CardView} widget to <a
+ href="{@docRoot}training/material/lists-cards.html#CardView">create cards</a>.</li>
+<li>The {@link android.support.v7.graphics.Palette} class to <a
+ href="{@docRoot}training/material/drawables.html#ColorExtract">extract prominent colors from
+ images</a>.</li>
+</ul>
+
+<h3>System widgets</h3>
+
+<p>The <code>Theme.AppCompat</code> themes provide material design styles for these widgets:</p>
+
+<ul>
+ <li>{@link android.widget.EditText}</li>
+ <li>{@link android.widget.Spinner}</li>
+ <li>{@link android.widget.CheckBox}</li>
+ <li>{@link android.widget.RadioButton}</li>
+ <li>{@link android.support.v7.widget.SwitchCompat}</li>
+ <li>{@link android.widget.CheckedTextView}</li>
+</ul>
+
+<h3>Color Palette</h3>
+
+<p>To obtain material design styles and customize the color palette with the Android v7 Support
+Library, apply one of the <code>Theme.AppCompat</code> themes:</p>
+
+<pre>
+&lt;!-- extend one of the Theme.AppCompat themes -->
+&lt;style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
+ &lt;!-- customize the color palette -->
+ &lt;item name="colorPrimary">@color/material_blue_500&lt;/item>
+ &lt;item name="colorPrimaryDark">@color/material_blue_700&lt;/item>
+ &lt;item name="colorAccent">@color/material_green_A200&lt;/item>
+&lt;/style>
+</pre>
+
+<h3>Lists and Cards</h3>
+
+<p>The {@link android.support.v7.widget.RecyclerView} and {@link
+android.support.v7.widget.CardView} widgets are available in earlier versions of Android through
+the Android v7 Support Library with these limitations:</p>
+<ul>
+<li>{@link android.support.v7.widget.CardView} falls back to a programmatic shadow implementation
+ using additional padding.</li>
+<li>{@link android.support.v7.widget.CardView} does not clip its children views that intersect
+ with rounded corners.</li>
+</ul>
+
+
+<h3>Dependencies</h3>
+
+<p>To use these features in versions of Android earlier than 5.0 (API level 21), include the
+Android v7 Support Library in your project as a <a
+href="{@docRoot}/sdk/installing/studio-build.html#dependencies">Gradle dependency</a>:</p>
+
+<pre>
+dependencies {
+ compile 'com.android.support:appcompat-v7:+'
+ compile 'com.android.support:cardview-v7:+'
+ compile 'com.android.support:recyclerview-v7:+'
+}
+</pre>
+
+
+<h2 id="CheckVersion">Check the System Version</h2>
+
+<p>The following features are available only in Android 5.0 (API level 21) and above:</p>
+
+<ul>
+<li>Activity transitions</li>
+<li>Touch feedback</li>
+<li>Reveal animations</li>
+<li>Path-based animations</li>
+<li>Vector drawables</li>
+<li>Drawable tinting</li>
+</ul>
+
+<p>To preserve compatibility with earlier versions of Android, check the system {@link
+android.os.Build.VERSION#SDK_INT version} at runtime before you invoke the APIs for any of these
+features:</p>
+
+<pre>
+// Check if we're running on Android 5.0 or higher
+if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ // Call some material design APIs here
+} else {
+ // Implement this feature without material design
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> To specify which versions of Android your app supports,
+use the <code>android:minSdkVersion</code> and <code>android:targetSdkVersion</code>
+attributes in your manifest file. To use the material design features in Android 5.0, set
+the <code>android:targetSdkVersion</code> attribute to <code>21</code>. For more information, see
+the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt; API
+guide</a>.</p>
diff --git a/docs/html/training/material/drawables.jd b/docs/html/training/material/drawables.jd
new file mode 100644
index 0000000..8d7f453
--- /dev/null
+++ b/docs/html/training/material/drawables.jd
@@ -0,0 +1,119 @@
+page.title=Working with Drawables
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#DrawableTint">Tint Drawable Resources</a></li>
+ <li><a href="#ColorExtract">Extract Prominent Colors from an Image</a></li>
+ <li><a href="#VectorDrawables">Create Vector Drawables</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">Material design specification</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Material design on Android</a></li>
+</ul>
+</div>
+</div>
+
+<p>The following capabilities for drawables help you implement material design in your apps:</p>
+
+<ul>
+<li>Drawable tinting</li>
+<li>Prominent color extraction</li>
+<li>Vector drawables</li>
+</ul>
+
+<p>This lesson shows you how to use these features in your app.</p>
+
+
+<h2 id="DrawableTint">Tint Drawable Resources</h2>
+
+<p>With Android 5.0 (API level 21) and above, you can tint bitmaps and nine-patches defined as
+alpha masks. You can tint them with color resources or theme attributes that resolve to color
+resources (for example, <code>?android:attr/colorPrimary</code>). Usually, you create these assets
+only once and color them automatically to match your theme.</p>
+
+<p>You can apply a tint to {@link android.graphics.drawable.BitmapDrawable} or {@link
+android.graphics.drawable.NinePatchDrawable} objects with the {@code setTint()} method. You can
+also set the tint color and mode in your layouts with the <code>android:tint</code> and
+<code>android:tintMode</code> attributes.</p>
+
+
+<h2 id="ColorExtract">Extract Prominent Colors from an Image</h2>
+
+<p>The Android Support Library r21 and above includes the {@link
+android.support.v7.graphics.Palette} class, which lets you extract prominent colors from an image.
+This class extracts the following prominent colors:</p>
+
+<ul>
+<li>Vibrant</li>
+<li>Vibrant dark</li>
+<li>Vibrant light</li>
+<li>Muted</li>
+<li>Muted dark</li>
+<li>Muted light</li>
+</ul>
+
+<p>To extract these colors, pass a {@link android.graphics.Bitmap} object to the
+{@link android.support.v7.graphics.Palette#generate Palette.generate()} static method in the
+background thread where you load your images. If you can't use that thread, call the
+{@link android.support.v7.graphics.Palette#generateAsync Palette.generateAsync()} method and
+provide a listener instead.</p>
+
+<p>You can retrieve the prominent colors from the image using the getter methods in the
+<code>Palette</code> class, such as <code>Palette.getVibrantColor</code>.</p>
+
+<p>To use the {@link android.support.v7.graphics.Palette} class in your project, add the following
+<a href="{@docRoot}sdk/installing/studio-build.html#dependencies">Gradle dependency</a> to your
+app's module:</p>
+
+<pre>
+dependencies {
+ ...
+ compile 'com.android.support:palette-v7:+'
+}
+</pre>
+
+<p>For more information, see the API reference for the {@link android.support.v7.graphics.Palette}
+class.</p>
+
+
+<h2 id="VectorDrawables">Create Vector Drawables</h2>
+
+<p>In Android 5.0 (API Level 21) and above, you can define vector drawables, which scale without
+losing definition. You need only one asset file for a vector image, as opposed to an asset file for
+each screen density in the case of bitmap images. To create a vector image, you define the details
+of the shape inside a <code>&lt;vector&gt;</code> XML element.</p>
+
+<p>The following example defines a vector image with the shape of a heart:</p>
+
+<pre>
+&lt;!-- res/drawable/heart.xml -->
+&lt;vector xmlns:android="http://schemas.android.com/apk/res/android"
+ &lt;!-- intrinsic size of the drawable -->
+ android:height="256dp"
+ android:width="256dp"
+ &lt;!-- size of the virtual canvas -->
+ android:viewportWidth="32"
+ android:viewportHeight="32">
+
+ &lt;!-- draw a path -->
+ &lt;path android:fillColor="#8fff"
+ android:pathData="M20.5,9.5
+ c-1.955,0,-3.83,1.268,-4.5,3
+ c-0.67,-1.732,-2.547,-3,-4.5,-3
+ C8.957,9.5,7,11.432,7,14
+ c0,3.53,3.793,6.257,9,11.5
+ c5.207,-5.242,9,-7.97,9,-11.5
+ C25,11.432,23.043,9.5,20.5,9.5z" />
+&lt;/vector>
+</pre>
+
+<p>Vector images are represented in Android as {@link android.graphics.drawable.VectorDrawable}
+objects. For more information about the <code>pathData</code> syntax, see the <a
+href="http://www.w3.org/TR/SVG11/paths.html#PathData">SVG Path reference</a>. For more information
+about animating the properties of vector drawables, see
+<a href="{@docRoot}training/material/animations.html#AnimVector">Animating Vector Drawables</a>.</p>
diff --git a/docs/html/training/material/get-started.jd b/docs/html/training/material/get-started.jd
new file mode 100644
index 0000000..b6088eb
--- /dev/null
+++ b/docs/html/training/material/get-started.jd
@@ -0,0 +1,173 @@
+page.title=Getting Started
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#ApplyTheme">Apply the Material Theme</a></li>
+ <li><a href="#Layouts">Design Your Layouts</a></li>
+ <li><a href="#Depth">Specify Elevation in Your Views</a></li>
+ <li><a href="#ListsCards">Create Lists and Cards</a></li>
+ <li><a href="#Animations">Customize Your Animations</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">Material design specification</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Material design on Android</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>To create apps with material design:</p>
+
+<ol>
+ <li style="margin-bottom:10px">
+ Review the <a href="http://www.google.com/design/spec">material design specification</a>.</li>
+ <li style="margin-bottom:10px">
+ Apply the material <strong>theme</strong> to your app.</li>
+ <li style="margin-bottom:10px">
+ Create your <strong>layouts</strong> following material design guidelines.</li>
+ <li style="margin-bottom:10px">
+ Specify the <strong>elevation</strong> of your views to cast shadows.</li>
+ <li style="margin-bottom:10px">
+ Use system <strong>widgets</strong> for lists and cards.</li>
+ <li style="margin-bottom:10px">
+ Customize the <strong>animations</strong> in your app.</li>
+</ol>
+
+<h3>Maintain backward compatibility</h3>
+
+<p>You can add many material design features to your app while maintaining compatibility with
+versions of Android earlier than 5.0. For more information, see
+<a href="{@docRoot}training/material/compatibility.html">Maintaining Compatibility</a>.</p>
+
+<h3>Update your app with material design</h3>
+
+<p>To update an existing app to incorporate material design, update your layouts following
+material design guidelines. Also make sure to incorporate depth, touch feedback, and
+animations.</p>
+
+<h3>Create new apps with material design</h3>
+
+<p>If you are creating a new app with material design features, the <a
+href="http://www.google.com/design/spec">material design guidelines</a> provide you with a
+cohesive design framework. Follow those guidelines and use the new functionality in the Android
+framework to design and develop your app.</p>
+
+
+<h2 id="ApplyTheme">Apply the Material Theme</h2>
+
+<p>To apply the material theme in your app, specify a style that inherits from
+<code>android:Theme.Material</code>:</p>
+
+<pre>
+&lt;!-- res/values/styles.xml -->
+&lt;resources>
+ &lt;!-- your theme inherits from the material theme -->
+ &lt;style name="AppTheme" parent="android:Theme.Material">
+ &lt;!-- theme customizations -->
+ &lt;/style>
+&lt;/resources>
+</pre>
+
+<p>The material theme provides updated system widgets that let you set their color palette and
+default animations for touch feedback and activity transitions. For more details, see
+<a href="{@docRoot}training/material/theme.html">Using the Material Theme</a>.</p>
+
+
+<h2 id="Layouts">Design Your Layouts</h2>
+
+<p>In addition to applying and customizing the material theme, your layouts should conform to
+the <a href="http://www.google.com/design/spec">material design guidelines</a>. When you design
+your layouts, pay special attention to the following:</p>
+
+<ul>
+<li>Baseline grids</li>
+<li>Keylines</li>
+<li>Spacing</li>
+<li>Touch target size</li>
+<li>Layout structure</li>
+</ul>
+
+
+<h2 id="Depth">Specify Elevation in Your Views</h2>
+
+<p>Views can cast shadows, and the elevation value of a view
+determines the size of its shadow and its drawing order. To set the elevation of a view, use the
+<code>android:elevation</code> attribute in your layouts:</p>
+
+<pre>
+&lt;TextView
+ android:id="&#64;+id/my_textview"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="&#64;string/next"
+ android:background="&#64;color/white"
+ android:elevation="5dp" />
+</pre>
+
+<p>The new <code>translationZ</code> property lets you create animations that reflect temporary
+changes in the elevation of a view. Elevation changes can be useful when
+<a href="{@docRoot}training/material/animations.html#ViewState">responding to touch
+gestures</a>.</p>
+
+<p>For more details, see <a href="{@docRoot}training/material/shadows-clipping.html">Defining
+Shadows and Clipping Views</a>.</p>
+
+
+<h2 id="ListsCards">Create Lists and Cards</h2>
+
+<p>{@link android.support.v7.widget.RecyclerView} is a more pluggable version of {@link
+android.widget.ListView} that supports different layout types and provides performance improvements.
+{@link android.support.v7.widget.CardView} lets you show pieces of information inside cards with
+a consistent look across apps. The following code example demonstrates how to include a
+{@link android.support.v7.widget.CardView} in your layout:</p>
+
+<pre>
+&lt;android.support.v7.widget.CardView
+ android:id="&#64;+id/card_view"
+ android:layout_width="200dp"
+ android:layout_height="200dp"
+ card_view:cardCornerRadius="3dp">
+ ...
+&lt;/android.support.v7.widget.CardView>
+</pre>
+
+<p>For more information, see <a href="{@docRoot}training/material/lists-cards.html">Creating Lists
+and Cards</a>.</p>
+
+
+<h2 id="Animations">Customize Your Animations</h2>
+
+<p>Android 5.0 (API level 21) includes new APIs to create custom animations in your app.
+For example, you can enable activity transitions and define an exit transition inside an
+activity:</p>
+
+<pre>
+public class MyActivity extends Activity {
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // enable transitions
+ getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
+ setContentView(R.layout.activity_my);
+ }
+
+ public void onSomeButtonClicked(View view) {
+ getWindow().setExitTransition(new Explode());
+ Intent intent = new Intent(this, MyOtherActivity.class);
+ startActivity(intent,
+ ActivityOptions
+ .makeSceneTransitionAnimation(this).toBundle());
+ }
+}
+</pre>
+
+<p>When you start another activity from this activity, the exit transition is activated.</p>
+
+<p>To learn more about the new animation APIs, see <a
+href="{@docRoot}training/material/animations.html">Defining Custom Animations</a>.</p>
diff --git a/docs/html/training/material/images/RecyclerView.png b/docs/html/training/material/images/RecyclerView.png
new file mode 100644
index 0000000..364951d
--- /dev/null
+++ b/docs/html/training/material/images/RecyclerView.png
Binary files differ
diff --git a/docs/html/training/material/images/SceneTransition.png b/docs/html/training/material/images/SceneTransition.png
new file mode 100644
index 0000000..ae82820
--- /dev/null
+++ b/docs/html/training/material/images/SceneTransition.png
Binary files differ
diff --git a/docs/html/training/material/images/ThemeColors.png b/docs/html/training/material/images/ThemeColors.png
new file mode 100644
index 0000000..b3c570b
--- /dev/null
+++ b/docs/html/training/material/images/ThemeColors.png
Binary files differ
diff --git a/docs/html/training/material/images/shadows-depth.png b/docs/html/training/material/images/shadows-depth.png
new file mode 100644
index 0000000..26b6b4a
--- /dev/null
+++ b/docs/html/training/material/images/shadows-depth.png
Binary files differ
diff --git a/docs/html/training/material/index.jd b/docs/html/training/material/index.jd
new file mode 100644
index 0000000..542a941
--- /dev/null
+++ b/docs/html/training/material/index.jd
@@ -0,0 +1,62 @@
+page.title=Creating Apps with Material Design
+page.type=design
+page.image=design/material/images/MaterialLight.png
+page.metaDescription=Learn how to apply material design to your apps.
+
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+ <ul>
+ <li>Android 5.0 (API level 21)</li>
+ <li>Android Studio 0.8</li>
+ </ul>
+</div>
+</div>
+
+<p>Material design is a comprehensive guide for visual, motion, and interaction design across
+platforms and devices. To use material design in your Android apps, follow the guidelines
+described in the
+<a href="http://www.google.com/design/spec/material-design/introduction.html">material design
+specification</a> and use the new components and functionality available in Android 5.0
+(API level 21).</p>
+
+<p>This class shows you how to create material design apps with the following elements:</p>
+
+<ul>
+<li>The material theme</li>
+<li>Widgets for cards and lists</li>
+<li>Custom shadows and view clipping</li>
+<li>Vector drawables</li>
+<li>Custom animations</li>
+</ul>
+
+<p>This class also teaches you how to maintain compatibility with versions of Android earlier than
+5.0 (API level 21) when you use material design features in your app.</p>
+
+<h2>Lessons</h2>
+
+<dl>
+ <dt><a href="{@docRoot}training/material/get-started.html">Getting Started</a></dt>
+ <dd>Learn how to update your app with material design features.</dd>
+
+ <dt><a href="{@docRoot}training/material/theme.html">Using the Material Theme</a></dt>
+ <dd>Learn how to apply material design styles to your app.</dd>
+
+ <dt><a href="{@docRoot}training/material/lists-cards.html">Creating Lists and Cards</a></dt>
+ <dd>Learn how to create lists and cards with a consistent look and feel using system widgets.</dd>
+
+ <dt><a href="{@docRoot}training/material/shadows-clipping.html">Defining Shadows and Clipping Views</a></dt>
+ <dd>Learn how to set elevation for your views to create custom shadows and how to clip views.</dd>
+
+ <dt><a href="{@docRoot}training/material/drawables.html">Working with Drawables</a></dt>
+ <dd>Learn how to create vector drawables and how to tint drawable resources.</dd>
+
+ <dt><a href="{@docRoot}training/material/animations.html">Defining Custom Animations</a></dt>
+ <dd>Learn how to create custom animations for views and activity transitions with shared elements.</dd>
+
+ <dt><a href="{@docRoot}training/material/compatibility.html">Maintaining Compatibility</a></dt>
+ <dd>Learn how to maintain compatibility with platform versions earlier than Android 5.0.</dd>
+</dl>
diff --git a/docs/html/training/material/lists-cards.jd b/docs/html/training/material/lists-cards.jd
new file mode 100644
index 0000000..eb45f0d
--- /dev/null
+++ b/docs/html/training/material/lists-cards.jd
@@ -0,0 +1,266 @@
+page.title=Creating Lists and Cards
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#RecyclerView">Create Lists</a></li>
+ <li><a href="#CardView">Create Cards</a></li>
+ <li><a href="#Dependencies">Add Dependencies</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">Material design specification</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Material design on Android</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>To create complex lists and cards with material design styles in your apps, you can use the
+{@link android.support.v7.widget.RecyclerView} and {@link android.support.v7.widget.CardView}
+widgets.</p>
+
+
+<h2 id="RecyclerView">Create Lists</h2>
+
+<p>The {@link android.support.v7.widget.RecyclerView} widget is a more advanced and flexible
+version of {@link android.widget.ListView}. This widget is a container for displaying large data
+sets that can be scrolled very efficiently by maintaining a limited number of views. Use the
+{@link android.support.v7.widget.RecyclerView} widget when you have data collections whose elements
+change at runtime based on user action or network events.</p>
+
+<p>The {@link android.support.v7.widget.RecyclerView} class simplifies the display and handling of
+large data sets by providing:</p>
+
+<ul>
+ <li>Layout managers for positioning items</li>
+ <li>Default animations for common item operations, such as removal or addition of items</li>
+</ul>
+
+<p>You also have the flexibility to define custom layout managers and animations for {@link
+android.support.v7.widget.RecyclerView} widgets.</p>
+
+<img src="{@docRoot}training/material/images/RecyclerView.png" alt="" width="550" height="106"/>
+<p class="img-caption">
+<strong>Figure 1</strong>. The <code>RecyclerView</code> widget.
+</p>
+
+<p>To use the {@link android.support.v7.widget.RecyclerView} widget, you have to specify an
+adapter and a layout manager. To create an adapter, extend the {@link
+android.support.v7.widget.RecyclerView.Adapter RecyclerView.Adapter} class. The details
+of the implementation depend on the specifics of your dataset and the type of views. For more
+information, see the <a href="#RVExamples">examples</a> below.</p>
+
+<div style="float:right">
+<img src="{@docRoot}design/material/images/list_mail.png" alt="" width="250" height="426"/>
+<p class="img-caption" style="margin-left:8px">
+<strong>Figure 2</strong> - Lists with <code>RecyclerView</code>.
+</p>
+</div>
+
+<p>A <strong>layout manager</strong> positions item views inside a {@link
+android.support.v7.widget.RecyclerView} and determines when to reuse item views that are no
+longer visible to the user. To reuse (or <em>recycle</em>) a view, a layout manager may ask the
+adapter to replace the contents of the view with a different element from the dataset. Recycling
+views in this manner improves performance by avoiding the creation of unnecessary views or
+performing expensive {@link android.app.Activity#findViewById findViewById()} lookups.</p>
+
+<p>{@link android.support.v7.widget.RecyclerView} provides these built-in layout managers:</p>
+
+<ul>
+<li>{@link android.support.v7.widget.LinearLayoutManager} shows items in a vertical or horizontal
+scrolling list.</li>
+<li>{@link android.support.v7.widget.GridLayoutManager} shows items in a grid.</li>
+<li>{@link android.support.v7.widget.StaggeredGridLayoutManager} shows items in a staggered grid.</li>
+</ul>
+
+<p>To create a custom layout manager, extend the {@link
+android.support.v7.widget.RecyclerView.LayoutManager RecyclerView.LayoutManager} class.</p>
+
+<h3>Animations</h3>
+
+<p>Animations for adding and removing items are enabled by default in {@link
+android.support.v7.widget.RecyclerView}. To customize these animations, extend the
+{@link android.support.v7.widget.RecyclerView.ItemAnimator RecyclerView.ItemAnimator} class and use
+the {@link android.support.v7.widget.RecyclerView#setItemAnimator RecyclerView.setItemAnimator()}
+method.</p>
+
+<h3 id="RVExamples">Examples</h3>
+
+<p>The following code example demonstrates how to add the
+{@link android.support.v7.widget.RecyclerView} to a layout:</p>
+
+<pre>
+&lt;!-- A RecyclerView with some commonly used attributes -->
+&lt;android.support.v7.widget.RecyclerView
+ android:id="@+id/my_recycler_view"
+ android:scrollbars="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+</pre>
+
+<p>Once you have added a {@link android.support.v7.widget.RecyclerView} widget to your layout,
+obtain a handle to the object, connect it to a layout manager, and attach an adapter for the data
+to be displayed:</p>
+
+<pre>
+public class MyActivity extends Activity {
+ private RecyclerView mRecyclerView;
+ private RecyclerView.Adapter mAdapter;
+ private RecyclerView.LayoutManager mLayoutManager;
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.my_activity);
+ mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
+
+ // use this setting to improve performance if you know that changes
+ // in content do not change the layout size of the RecyclerView
+ mRecyclerView.setHasFixedSize(true);
+
+ // use a linear layout manager
+ mLayoutManager = new LinearLayoutManager(this);
+ mRecyclerView.setLayoutManager(mLayoutManager);
+
+ // specify an adapter (see also next example)
+ mAdapter = new MyAdapter(myDataset);
+ mRecyclerView.setAdapter(mAdapter);
+ }
+ ...
+}
+</pre>
+
+<p>The adapter provides access to the items in your data set, creates views for items, and
+replaces the content of some of the views with new data items when the original item is no longer
+visible. The following code example shows a simple implementation for a data set that consists
+of an array of strings displayed using {@link android.widget.TextView} widgets:</p>
+
+<pre>
+public class MyAdapter extends RecyclerView.Adapter&lt;MyAdapter.ViewHolder> {
+ private String[] mDataset;
+
+ // Provide a reference to the views for each data item
+ // Complex data items may need more than one view per item, and
+ // you provide access to all the views for a data item in a view holder
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+ // each data item is just a string in this case
+ public TextView mTextView;
+ public ViewHolder(TextView v) {
+ super(v);
+ mTextView = v;
+ }
+ }
+
+ // Provide a suitable constructor (depends on the kind of dataset)
+ public MyAdapter(String[] myDataset) {
+ mDataset = myDataset;
+ }
+
+ // Create new views (invoked by the layout manager)
+ &#64;Override
+ public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
+ int viewType) {
+ // create a new view
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.my_text_view, parent, false);
+ // set the view's size, margins, paddings and layout parameters
+ ...
+ ViewHolder vh = new ViewHolder(v);
+ return vh;
+ }
+
+ // Replace the contents of a view (invoked by the layout manager)
+ &#64;Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ // - get element from your dataset at this position
+ // - replace the contents of the view with that element
+ holder.mTextView.setText(mDataset[position]);
+
+ }
+
+ // Return the size of your dataset (invoked by the layout manager)
+ &#64;Override
+ public int getItemCount() {
+ return mDataset.length;
+ }
+}
+</pre>
+
+
+<div style="float:right;margin-top:15px;margin-left:30px">
+<img src="{@docRoot}design/material/images/card_travel.png" alt="" width="225" height="383">
+<p class="img-caption" style="margin-left:12px">
+<strong>Figure 3</strong>. Card examples.
+</p>
+</div>
+
+<h2 id="CardView">Create Cards</h2>
+
+<p>{@link android.support.v7.widget.CardView} extends the {@link android.widget.FrameLayout} class
+and lets you show information inside cards that have a consistent look across the platform. {@link
+android.support.v7.widget.CardView} widgets can have shadows and rounded corners.</p>
+
+<p>To create a card with a shadow, use the <code>card_view:cardElevation</code> attribute.
+{@link android.support.v7.widget.CardView} uses real elevation and dynamic shadows on Android 5.0
+(API level 21) and above and falls back to a programmatic shadow implementation on earlier versions.
+For more information, see <a href="{@docRoot}training/material/compatibility.html">Maintaining
+Compatibility</a>.</p>
+
+<p>Use these properties to customize the appearance of the
+{@link android.support.v7.widget.CardView} widget:</p>
+
+<ul>
+ <li>To set the corner radius in your layouts, use the <code>card_view:cardCornerRadius</code>
+ attribute.</li>
+ <li>To set the corner radius in your code, use the <code>CardView.setRadius</code> method.</li>
+ <li>To set the background color of a card, use the <code>card_view:cardBackgroundColor</code>
+attribute.</li>
+</ul>
+
+<p>The following code example shows you how to include a {@link android.support.v7.widget.CardView}
+widget in your layout:</p>
+
+<pre>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:card_view="http://schemas.android.com/apk/res-auto"
+ ... >
+ &lt;!-- A CardView that contains a TextView -->
+ &lt;android.support.v7.widget.CardView
+ xmlns:card_view="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/card_view"
+ android:layout_gravity="center"
+ android:layout_width="200dp"
+ android:layout_height="200dp"
+ card_view:cardCornerRadius="4dp">
+
+ &lt;TextView
+ android:id="@+id/info_text"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ &lt;/android.support.v7.widget.CardView>
+&lt;/LinearLayout>
+</pre>
+
+<p>For more information, see the API reference for {@link android.support.v7.widget.CardView}.</p>
+
+
+<h2 id="Dependencies">Add Dependencies</h2>
+
+<p>The {@link android.support.v7.widget.RecyclerView} and {@link android.support.v7.widget.CardView}
+widgets are part of the <a href="{@docRoot}tools/support-library/features.html#v7">v7 Support
+Libraries</a>. To use these widgets in your project, add these
+<a href="{@docRoot}sdk/installing/studio-build.html#dependencies">Gradle dependencies</a> to your
+app's module:</p>
+
+<pre>
+dependencies {
+ ...
+ compile 'com.android.support:cardview-v7:+'
+ compile 'com.android.support:recyclerview-v7:+'
+}
+</pre>
diff --git a/docs/html/training/material/shadows-clipping.jd b/docs/html/training/material/shadows-clipping.jd
new file mode 100644
index 0000000..f58d780
--- /dev/null
+++ b/docs/html/training/material/shadows-clipping.jd
@@ -0,0 +1,127 @@
+page.title=Defining Shadows and Clipping Views
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#Elevation">Assign Elevation to Your Views</a></li>
+ <li><a href="#Shadows">Customize View Shadows and Outlines</a></li>
+ <li><a href="#Clip">Clip Views</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">Material design specification</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Material design on Android</a></li>
+</ul>
+</div>
+</div>
+
+<p>Material design introduces depth for UI elements. Depth helps users understand the relative
+importance of each element and focus their attention to the task at hand.</p>
+
+<p>The elevation of a view, represented by the Z property, determines the size of its shadow:
+views with higher Z values cast bigger shadows. Views only cast shadows on the Z=0 plane; they
+don't cast shadows on other views placed below them and above the Z=0 plane.</p>
+
+<p>Views with higher Z values occlude views with lower Z values. However, the Z value of a view
+does not affect the view's size.</p>
+
+<p>Elevation is also useful to create animations where widgets temporarily rise above the
+view plane when performing some action.</p>
+
+
+<h2 id="Elevation">Assign Elevation to Your Views</h2>
+
+<p>The Z value for a view has two components, elevation and translation. The elevation is the
+static component, and the translation is used for animations:</p>
+
+<p><code>Z = elevation + translationZ</code></p>
+
+<img src="{@docRoot}training/material/images/shadows-depth.png" width="680" height="177" alt=""/>
+<p class="img-caption"><strong>Figure 1</strong> - Shadows for different view elevations.</p>
+
+<p>To set the elevation of a view in a layout definition, use the <code>android:elevation</code>
+attribute. To set the elevation of a view in the code of an activity, use the
+{@link android.view.View#setElevation View.setElevation()} method.</p>
+
+<p>To set the translation of a view, use the {@link android.view.View#setTranslationZ
+View.setTranslationZ()} method.</p>
+
+<p>The new {@link android.view.ViewPropertyAnimator#z ViewPropertyAnimator.z()} and {@link
+android.view.ViewPropertyAnimator#translationZ ViewPropertyAnimator.translationZ()} methods enable
+you to easily animate the elevation of views. For more information, see the API reference for
+{@link android.view.ViewPropertyAnimator} and the <a
+href="{@docRoot}guide/topics/graphics/prop-animation.html">Property Animation</a> developer
+guide.</p>
+
+<p>You can also use a {@link android.animation.StateListAnimator} to
+specify these animations in a declarative way. This is especially useful for cases where state
+changes trigger animations, like when a user presses a button. For more information, see
+<a href="{@docRoot}training/material/animations.html#ViewState">Animate View State Changes</a></p>.
+
+<p>The Z values are measured in the same units as the X and Y values.</p>
+
+
+<h2 id="Shadows">Customize View Shadows and Outlines</h2>
+
+<p>The bounds of a view's background drawable determine the default shape of its shadow.
+<strong>Outlines</strong> represent the outer shape of a graphics object and define the ripple
+area for touch feedback.</p>
+
+<p>Consider this view, defined with a background drawable:</p>
+
+<pre>
+&lt;TextView
+ android:id="@+id/myview"
+ ...
+ android:elevation="2dp"
+ android:background="@drawable/myrect" />
+</pre>
+
+<p>The background drawable is defined as a rectangle with rounded corners:</p>
+
+<pre>
+&lt;!-- res/drawable/myrect.xml -->
+&lt;shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ &lt;solid android:color="#42000000" />
+ &lt;corners android:radius="5dp" />
+&lt;/shape>
+</pre>
+
+<p>The view casts a shadow with rounded corners, since the background drawable defines the
+view's outline. Providing a custom outline overrides the default shape of a view's shadow.</p>
+
+<p>To define a custom outline for a view in your code:<p>
+
+<ol>
+<li>Extend the {@link android.view.ViewOutlineProvider} class.</li>
+<li>Override the {@link android.view.ViewOutlineProvider#getOutline getOutline()} method.</li>
+<li>Assign the new outline provider to your view with the {@link
+android.view.View#setOutlineProvider View.setOutlineProvider()} method.</li>
+</ol>
+
+<p>You can create oval and rectangular outlines with rounded corners using the methods in the
+{@link android.graphics.Outline} class. The default outline provider for views obtains the outline
+from the view's background. To prevent a view from casting a shadow, set its outline provider
+to <code>null</code>.</p>
+
+
+<h2 id="Clip">Clip Views</h2>
+
+<p>Clipping views enables you to easily change the shape of a view. You can clip views for
+consistency with other design elements or to change the shape of a view in response to user input.
+You can clip a view to its outline area using the {@link android.view.View#setClipToOutline
+View.setClipToOutline()} method or the <code>android:clipToOutline</code> attribute. Only
+rectangle, circle, and round rectangle outlines support clipping, as determined by the
+{@link android.graphics.Outline#canClip Outline.canClip()} method.</p>
+
+<p>To clip a view to the shape of a drawable, set the drawable as the background of the view
+(as shown above) and call the {@link android.view.View#setClipToOutline View.setClipToOutline()}
+method.</p>
+
+<p>Clipping views is an expensive operation, so don't animate the shape you use to
+clip a view. To achieve this effect, use the <a
+href="{@docRoot}training/material/animations.html#Reveal">Reveal Effect</a> animation.</p>
diff --git a/docs/html/training/material/theme.jd b/docs/html/training/material/theme.jd
new file mode 100644
index 0000000..17894f6
--- /dev/null
+++ b/docs/html/training/material/theme.jd
@@ -0,0 +1,131 @@
+page.title=Using the Material Theme
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#ColorPalette">Customize the Color Palette</a></li>
+ <li><a href="#StatusBar">Customize the Status Bar</a></li>
+ <li><a href="#Inheritance">Theme Individual Views</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">Material design specification</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Material design on Android</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>The new material theme provides:</p>
+
+<ul>
+ <li>System widgets that let you set their color palette</li>
+ <li>Touch feedback animations for the system widgets</li>
+ <li>Activity transition animations</li>
+</ul>
+
+<p>You can customize the look of the material theme
+according to your brand identity with a color palette you control. You can tint the action bar and
+the status bar using theme attributes, as shown in <a href="#fig3">Figure 3</a>.</p>
+
+<p>The system widgets have a new design and touch feedback animations. You can customize the
+color palette, the touch feedback animations, and the activity transitions for your app.</p>
+
+<p>The material theme is defined as:</p>
+
+<ul>
+ <li><code>@android:style/Theme.Material</code> (dark version)</li>
+ <li><code>@android:style/Theme.Material.Light</code> (light version)</li>
+ <li><code>@android:style/Theme.Material.Light.DarkActionBar</code></li>
+</ul>
+
+<p>For a list of material styles that you can use, see the API reference for
+{@link android.R.style R.style}.</p>
+
+<!-- two columns, dark/light material theme example -->
+<div style="width:700px;margin-top:25px;margin-bottom:10px">
+<div style="float:left;width:250px;margin-left:40px;margin-right:60px;">
+ <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238">
+ <div style="width:170px;margin:0 auto">
+ <p style="margin-top:8px;font-size:12px"><strong>Figure 1</strong>. Dark material theme</p>
+ </div>
+</div>
+<div style="float:left;width:250px;margin-right:0px;">
+ <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238">
+ <div style="width:170px;margin:0 auto">
+ <p style="margin-top:8px;font-size:12px"><strong>Figure 2</strong>. Light material theme</p>
+ </div>
+</div>
+<br style="clear:left">
+</div>
+
+<p class="note">
+<strong>Note:</strong> The material theme is only available in Android 5.0 (API level 21) and
+above. The <a href="{@docRoot}tools/support-library/features.html#v7">v7 Support Libraries</a>
+provide themes with material design styles for some widgets and support for customizing the color
+palette. For more information, see
+<a href="{@docRoot}training/material/compatibility.html">Maintaining Compatibility</a>.
+</p>
+
+
+<h2 id="ColorPalette">Customize the Color Palette</h2>
+
+<p style="margin-bottom:30px">To customize the theme's base colors to fit your brand, define
+your custom colors using theme attributes when you inherit from the material theme:</p>
+
+<pre>
+&lt;resources>
+ &lt;!-- inherit from the material theme -->
+ &lt;style name="AppTheme" parent="android:Theme.Material">
+ &lt;!-- Main theme colors -->
+ &lt;!-- your app branding color for the app bar -->
+ &lt;item name="android:colorPrimary">@color/primary&lt;/item>
+ &lt;!-- darker variant for the status bar and contextual app bars -->
+ &lt;item name="android:colorPrimaryDark">@color/primary_dark&lt;/item>
+ &lt;!-- theme UI controls like checkboxes and text fields -->
+ &lt;item name="android:colorAccent">@color/accent&lt;/item>
+ &lt;/style>
+&lt;/resources>
+</pre>
+
+<div style="float:right;margin-left:25px;margin-top:20px;margin-bottom:10px" id="fig3">
+<img src="{@docRoot}training/material/images/ThemeColors.png" width="250" height="445"/>
+<p class="img-caption" style="margin-bottom:0px">
+<strong>Figure 3.</strong> Customizing the material theme.</p>
+</div>
+
+
+<h2 id="StatusBar">Customize the Status Bar</h2>
+
+<p>The material theme lets you easily customize the status bar, so you can specify a
+color that fits your brand and provides enough contrast to show the white status icons. To
+set a custom color for the status bar, use the <code>android:statusBarColor</code> attribute when
+you extend the material theme. By default, <code>android:statusBarColor</code> inherits the
+value of <code>android:colorPrimaryDark</code>.</p>
+
+<p>You can also draw behind the status bar yourself. For example, if you want to show
+the status bar transparently over a photo, with a subtle dark gradient to ensure the white
+status icons are visible. To do so, set the <code>android:statusBarColor</code> attribute to
+<code>&#64;android:color/transparent</code> and adjust the window flags as required. You can
+also use the {@link android.view.Window#setStatusBarColor Window.setStatusBarColor()} method for
+animations or fading.</p>
+
+<p class="note">
+<strong>Note:</strong> The status bar should almost always have a clear delineation from the
+primary toolbar, except for cases where you show edge-to-edge rich imagery or media content behind
+these bars and when you use a gradient to ensure that the icons are still visible.
+</p>
+
+<p>When you customize the navigation and status bars, either make them both transparent or modify
+only the status bar. The navigation bar should remain black in all other cases.</p>
+
+
+<h2 id="Inheritance">Theme Individual Views</h3>
+
+<p>Elements in XML layout definitions can specify the <code>android:theme</code> attribute,
+which references a theme resource. This attribute modifies the theme for the element and any
+child elements, which is useful for altering theme color palettes in a specific portion
+of an interface.</p>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 5443c56..0fee771 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -836,9 +836,103 @@ include the action bar on devices running Android 2.1 or higher."
</li>
</ul>
</li>
-
<!-- End Building for wearables -->
+
+ <!-- Start: Building for TV -->
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/tv/index.html">
+ <span class="small">Building Apps for</span><br/>
+ TV
+ </a>
+ </div>
+ <ul>
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+
+ <a href="<?cs var:toroot ?>training/tv/start/index.html"
+ description="How to start building TV apps or extend your existing app to run on TV
+ devices.">
+ Building TV Apps</a>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/start/start.html">
+ Getting Started with TV Apps</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/start/hardware.html">
+ Handling TV Hardware</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/start/layouts.html">
+ Building TV Layouts</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/start/navigation.html">
+ Creating TV Navigation</a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/tv/playback/index.html"
+ description="How to build apps that provide media catalogs and play content.">
+ Building TV Playback Apps</a>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/playback/browse.html">
+ Creating a Catalog Browser</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/playback/details.html">
+ Building a Details View</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/playback/now-playing.html">
+ Displaying a Now Playing Card</a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/tv/discovery/index.html"
+ description="How to help users discover content from your app.">
+ Helping Users Find Content on TV</a>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/discovery/recommendations.html">
+ Recommending TV Content</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/discovery/in-app-search.html">
+ Searching within TV Apps</a>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/games/index.html"
+ description="How to build games for TV.">
+ Building TV Games</a>
+ </li>
+
+ <li>
+ <a href="<?cs var:toroot ?>training/tv/tif/index.html"
+ description="How to build Live TV apps.">
+ Building Live TV Apps</a>
+ </li>
+ </ul>
+ </li>
+ <!-- End: Building for TV -->
+
+
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/best-ux.html">
@@ -1046,29 +1140,6 @@ results."
</li>
<li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>training/tv/index.html"
- description=
- "How to optimize your app's user interface and user input for
- the &quot;ten foot experience&quot; of a TV screen."
- >Designing for TV</a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot ?>training/tv/optimizing-layouts-tv.html">
- Optimizing Layouts for TV
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>training/tv/optimizing-navigation-tv.html">
- Optimizing Navigation for TV
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>training/tv/unsupported-features-tv.html">
- Handling Features Not Supported on TV
- </a>
- </li>
- </ul>
- </li>
-
- <li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/custom-views/index.html"
description=
@@ -1175,6 +1246,45 @@ results."
</ul>
</li>
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/material/index.html"
+ description=
+ "How to implement material design on Android."
+ >Creating Apps with Material Design</a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/material/get-started.html">
+ Getting Started
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/material/theme.html">
+ Using the Material Theme
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/material/lists-cards.html">
+ Creating Lists and Cards
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/material/shadows-clipping.html">
+ Defining Shadows and Clipping Views
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/material/drawables.html">
+ Working with Drawables
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/material/animations.html">
+ Defining Custom Animations
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/material/compatibility.html">
+ Maintaining Compatibility
+ </a>
+ </li>
+ </ul>
+ </li>
+
</ul>
</li>
<!-- End User Interface -->
diff --git a/docs/html/training/tv/discovery/in-app-search.jd b/docs/html/training/tv/discovery/in-app-search.jd
new file mode 100644
index 0000000..28c7a35
--- /dev/null
+++ b/docs/html/training/tv/discovery/in-app-search.jd
@@ -0,0 +1,145 @@
+page.title=Searching within TV Apps
+page.tags="leanback"
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#add-search-action">Add a Search Action</a></li>
+ <li><a href="#add-search-ui">Add Search Input and Results</a></li>
+ </ol>
+
+</div>
+</div>
+
+
+<p>
+ Users frequently have specific content in mind when using a media app on TV. If your app contains
+ a large catalog of content, browsing for a specific title may not be the most efficient way for
+ users to find what they are looking for. A search interface can help your users get to the
+ content they want faster than browsing.
+</p>
+
+<p>
+ The <a href="{@docRoot}tools/support-library/features.html#v17-leanback">Leanback support
+ library</a> provides a set of classes to enable a standard search interface within your app that
+ is consistent with other search functions on TV and provides features such as voice input.
+</p>
+
+<p>
+ This lesson discusses how to provide a search interface in your app using Leanback support
+ library classes.
+</p>
+
+
+<h2 id="add-search-action">Add a Search Action</h2>
+
+<p>
+ When you use the {@link android.support.v17.leanback.app.BrowseFragment} class for a media
+ browsing interface, you can enable a search interface as a standard part of the user
+ interface. The search interface is an icon that appears in the layout when you set {@link
+ android.view.View.OnClickListener} on the {@link android.support.v17.leanback.app.BrowseFragment}
+ object. The following sample code demonstrates this technique.
+</p>
+
+<pre>
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.browse_activity);
+
+ mBrowseFragment = (BrowseFragment)
+ getFragmentManager().findFragmentById(R.id.browse_fragment);
+
+ ...
+
+ mBrowseFragment.setOnSearchClickedListener(new View.OnClickListener() {
+ &#64;Override
+ public void onClick(View view) {
+ Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ mBrowseFragment.setAdapter(buildAdapter());
+}
+</pre>
+
+<p class="note">
+ <strong>Note:</strong> You can set the color of the search icon using the
+ {@link android.support.v17.leanback.app.BrowseFragment#setSearchAffordanceColor}.
+</p>
+
+
+<h2 id="add-search-ui">Add a Search Input and Results</h2>
+
+<p>
+ When a user selects the search icon, the system invokes a search activity via the defined intent.
+ Your search activity should use a linear layout containing a {@link
+ android.support.v17.leanback.app.SearchFragment}. This fragment must also implement the {@link
+ android.support.v17.leanback.app.SearchFragment.SearchResultProvider} interface in order to
+ display the results of a search.
+</p>
+
+<p>
+ The following code sample shows how to extend the {@link
+ android.support.v17.leanback.app.SearchFragment} class to provide a search interface and results:
+</p>
+
+<pre>
+public class MySearchFragment extends SearchFragment
+ implements SearchFragment.SearchResultProvider {
+
+ private static final int SEARCH_DELAY_MS = 300;
+ private ArrayObjectAdapter mRowsAdapter;
+ private Handler mHandler = new Handler();
+ private SearchRunnable mDelayedLoad;
+
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+ setSearchResultProvider(this);
+ setOnItemClickedListener(getDefaultItemClickedListener());
+ mDelayedLoad = new SearchRunnable();
+ }
+
+ &#64;Override
+ public ObjectAdapter getResultsAdapter() {
+ return mRowsAdapter;
+ }
+
+ &#64;Override
+ public boolean onQueryTextChange(String newQuery) {
+ mRowsAdapter.clear();
+ if (!TextUtils.isEmpty(newQuery)) {
+ mDelayedLoad.setSearchQuery(newQuery);
+ mHandler.removeCallbacks(mDelayedLoad);
+ mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
+ }
+ return true;
+ }
+
+ &#64;Override
+ public boolean onQueryTextSubmit(String query) {
+ mRowsAdapter.clear();
+ if (!TextUtils.isEmpty(query)) {
+ mDelayedLoad.setSearchQuery(query);
+ mHandler.removeCallbacks(mDelayedLoad);
+ mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
+ }
+ return true;
+ }
+}
+</pre>
+
+<p>
+ The example code shown above is meant to be used with a separate {@code SearchRunnable} class
+ that runs the search query on a separate thread. This technique keeps potentially slow-running
+ queries from blocking the main user interface thread.
+</p>
diff --git a/docs/html/training/tv/discovery/index.jd b/docs/html/training/tv/discovery/index.jd
new file mode 100644
index 0000000..fbc8c9f
--- /dev/null
+++ b/docs/html/training/tv/discovery/index.jd
@@ -0,0 +1,48 @@
+page.title=Helping Users Find Content on TV
+
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+ <ul>
+ <li>Android 5.0 (API level 21) or higher</li>
+ </ul>
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}design/tv/index.html">
+ Design for TV</a></li>
+ </ul>
+</div>
+</div>
+
+<p>
+ TV devices offer many entertainment options for users. They have thousands of content options
+ from apps and related content services. At the same time, most users prefer to use TVs with the
+ least amount of input possible. With the amount of choice available to users, it is important for
+ app developers to provide quick and easy paths for users to discover and enjoy your content.
+</p>
+
+<p>
+ The Android framework helps you provide a number of paths for users to discover your content,
+ including recommendations on the home screen and searching within your app's content catalog.
+</p>
+
+<p>
+ This class shows you how to help users discover your app's content through recommendations and
+ in-app searching.
+</p>
+
+
+<h2>Topics</h2>
+
+<dl>
+ <dt><b><a href="recommendations.html">Recommending TV Content</a></b></dt>
+ <dd>Learn how to recommend content for users so that it appears in the recommendations row
+ on the home screen of a TV device.</dd>
+
+ <dt><b><a href="in-app-search.html">Searching within TV Apps</a></b></dt>
+ <dd>Learn how to use a built-for-TV user interface for searching within your app.</dd>
+</dl>
diff --git a/docs/html/training/tv/discovery/recommendations.jd b/docs/html/training/tv/discovery/recommendations.jd
new file mode 100644
index 0000000..a6eb152
--- /dev/null
+++ b/docs/html/training/tv/discovery/recommendations.jd
@@ -0,0 +1,240 @@
+page.title=Recommending TV Content
+page.tags="recommendation","recommend"
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#service">Create a Recommendations Service</a></li>
+ <li><a href="#build">Build Recommendations</a></li>
+ <li><a href="#run-service">Run Recommendations Service</a></li>
+ </ol>
+</div>
+</div>
+
+<p>
+ When interacting with TVs, users generally prefer to give minimal input before watching
+ content. An ideal scenario for many TV users is: sit down, turn on, and watch. The fewest steps
+ to get users to content they enjoy is generally the path they prefer.
+</p>
+
+<p>
+ The Android framework assists with minimum-input interaction by providing a recommendations row
+ on the home screen. Content recommendations appear as the first row of the TV launch screen after
+ the first use of the device. Contributing recommendations from your app's content catalog can help
+ bring users back to your app.
+</p>
+
+<img src="{@docRoot}images/tv/home-recommendations.png" alt="" id="figure1" />
+<p class="img-caption">
+ <strong>Figure 1.</strong> An example of the recommendations row.
+</p>
+
+<p>
+ This lesson teaches you how to create recommendations and provide them to the Android framework
+ so your app content can be easily discovered and enjoyed by users.
+</p>
+
+
+<h2 id="service">Create a Recommendations Service</h2>
+
+<p>
+ Content recommendations are created with background processing. In order for your application to
+ contribute to recommendations, create a service that periodically adds listings from your
+ app's catalog to the system list of recommendations.
+</p>
+
+<p>
+ The following code example illustrates how to extend {@link android.app.IntentService} to
+ create a recommendation service for your application:
+</p>
+
+<pre>
+public class RecommendationsService extends IntentService {
+ private static final int MAX_RECOMMENDATIONS = 3;
+
+ public RecommendationsService() {
+ super("RecommendationService");
+ }
+
+ &#64;Override
+ protected void onHandleIntent(Intent intent) {
+ MovieDatabase database = MovieDatabase.instance(getApplicationContext());
+ List<Movie> recommendations = database.recommendations();
+
+ int count = 0;
+
+ try {
+ for (Movie movie : recommendations) {
+ // build the individual content recommendations
+ buildRecommendation(getApplicationContext(), movie);
+
+ if (++count >= MAX_RECOMMENDATIONS) {
+ break;
+ }
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to update recommendation", e);
+ }
+ }
+}
+</pre>
+
+<p>
+ In order for this service to be recognized by the system and run, register it using your
+ app manifest. The following code snippet illustrates how to declare this class as a service:
+</p>
+
+<pre>
+&lt;manifest ... &gt;
+ &lt;application ... &gt;
+ ...
+
+ &lt;service android:name=&quot;.RecommendationsService&quot;
+ android:enabled=&quot;true&quot; android:exported=&quot;true&quot;/&gt;
+ &lt;/application&gt;
+&lt;/manifest&gt;
+</pre>
+
+
+<h2 id="build">Build Recommendations</h2>
+
+<p>
+ Once your recommendation server starts running, it must create recommendations and pass them to
+ the Android framework. The framework receives the recommendations as {@link
+ android.app.Notification} objects that use a specific template and are marked with a specific
+ category.
+</p>
+
+<p>
+ The following code example demonstrates how to get an instance of the {@link
+ android.app.NotificationManager}, build a recommendation, and post it to the manager:
+</p>
+
+<pre>
+public class RecommendationsService extends IntentService {
+
+ ...
+
+ public Notification buildRecommendation(Context context, Movie movie)
+ throws IOException {
+
+ if (mNotificationManager == null) {
+ mNotificationManager = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ }
+
+ Bundle extras = new Bundle();
+ if (mBackgroundUri != movie.getBackgroundUri()) {
+ extras.putString(EXTRA_BACKGROUND_IMAGE_URL, movie.getBackgroundUri());
+ }
+
+ // build the recommendation as a Notification object
+ Notification notification = new NotificationCompat.BigPictureStyle(
+ new NotificationCompat.Builder(context)
+ .setContentTitle(movie.getTitle())
+ .setContentText(movie.getDescription())
+ .setContentInfo(APP_NAME)
+ .setGroup("ActionMovies")
+ .setSortKey("0.8")
+ .setPriority(movie.getPriority())
+ .setColor(#FFFF2020)
+ .setCategory("recommendation")
+ .setLargeIcon(movie.getImage())
+ .setSmallIcon(movie.getSmallIcon())
+ .setContentIntent(buildPendingIntent(movie.getId()))
+ .setExtras(extras))
+ .build();
+
+ // post the recommendation to the NotificationManager
+ mNotificationManager.notify(movie.getId(), notification);
+ mNotificationManager = null;
+ return notification;
+ }
+
+ private PendingIntent buildPendingIntent(long id) {
+ Intent detailsIntent = new Intent(this, DetailsActivity.class);
+ detailsIntent.putExtra("id", id);
+
+ TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
+ stackBuilder.addParentStack(DetailsActivity.class);
+ stackBuilder.addNextIntent(detailsIntent);
+ // Ensure each PendingIntent is unique
+ detailsIntent.setAction(Long.toString(id));
+
+ PendingIntent intent = stackBuilder.getPendingIntent(
+ 0, PendingIntent.FLAG_UPDATE_CURRENT);
+ return intent;
+ }
+}
+</pre>
+
+
+<h3 id="run-service">Run Recommendations Service</h3>
+
+<p>
+ Your app's recommendation service must run periodically in order to create current
+ recommendations. To run your service, create a class that runs a timer and invokes
+ it at regular intervals. The following code example extends the {@link
+ android.content.BroadcastReceiver} class to start periodic execution of a recommendation service
+ every 12 hours:
+</p>
+
+<pre>
+public class BootupReceiver extends BroadcastReceiver {
+ private static final String TAG = "BootupActivity";
+
+ private static final long INITIAL_DELAY = 5000;
+
+ &#64;Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().endsWith(Intent.ACTION_BOOT_COMPLETED)) {
+ scheduleRecommendationUpdate(context);
+ }
+ }
+
+ private void scheduleRecommendationUpdate(Context context) {
+ AlarmManager alarmManager = (AlarmManager)context.getSystemService(
+ Context.ALARM_SERVICE);
+ Intent recommendationIntent = new Intent(context,
+ UpdateRecommendationsService.class);
+ PendingIntent alarmIntent = PendingIntent.getService(context, 0,
+ recommendationIntent, 0);
+
+ alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ INITIAL_DELAY,
+ AlarmManager.INTERVAL_HALF_DAY,
+ alarmIntent);
+ }
+}
+</pre>
+
+<p>
+ This implementation of the {@link android.content.BroadcastReceiver} class must run after start
+ up of the TV device where it is installed. To accomplish this, register this class in your app
+ manifest with an intent filter that listens for the completion of the device boot process. The
+ following sample code demonstrates how to add this configuration to the manifest:
+</p>
+
+<pre>
+&lt;manifest ... &gt;
+ &lt;application ... &gt;
+ &lt;receiver android:name=&quot;.BootupReceiver&quot; android:enabled=&quot;true&quot;
+ android:exported=&quot;false&quot;&gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name=&quot;android.intent.action.BOOT_COMPLETED&quot;/&gt;
+ &lt;/intent-filter&gt;
+ &lt;/receiver&gt;
+ &lt;/application&gt;
+&lt;/manifest&gt;
+</pre>
+
+<p class="important">
+ <strong>Important:</strong> Receiving a boot completed notification requires that your app
+ requests the {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission.
+ For more information, see {@link android.content.Intent#ACTION_BOOT_COMPLETED}.
+</p>
diff --git a/docs/html/training/tv/games/index.jd b/docs/html/training/tv/games/index.jd
new file mode 100644
index 0000000..29b055b
--- /dev/null
+++ b/docs/html/training/tv/games/index.jd
@@ -0,0 +1,282 @@
+page.title=Building TV Games
+page.tags="controller"
+page.article=true
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#display">Display</a></li>
+ <li><a href="#control">Input Devices</a></li>
+ <li><a href="#manifest">Manifest</a></li>
+ <li><a href="#gpgs">Google Play Game Services</a></li>
+ <li><a href="#web">Web</a></li>
+ </ol>
+</div>
+</div>
+
+<p>
+ The television screen presents a number of considerations that may be new to mobile game
+ developers. These areas include its large size, its control scheme, and the fact that all players
+ are viewing it simultaneously.
+</p>
+
+
+<h2 id="display">Display</h2>
+<p>
+ The two main things to keep in mind when developing games for the TV screen are its nature as a
+ shared display and the need to design your game for a landscape orientation.
+</p>
+
+
+<h3 id="shared-display">Shared display</h3>
+
+<p>
+ A living-room TV poses design challenges for multiplayer games, in that all players can see
+ everything. This issue is especially relevant to games (such as card games or strategy games)
+ that rely on each player’s possession of hidden information.
+</p>
+
+<p>
+ Some mechanisms you can implement to address the problem of one player’s eavesdropping on
+ another’s information are:
+</p>
+
+<ul>
+ <li>A blinder on the screen to help conceal information. For example, in a turn-based game like a
+ word or card game, one player at a time might view the display. When the player finishes a move,
+ the game allows him or her to cover the screen with a blinder that blocks anyone from viewing
+ secret information. When the next player begins a turn, the blinder opens to reveal his or her
+ own information.
+ </li>
+ <li>A companion app, running on a phone or tablet, can enable a player to conceal information by
+ serving as a second screen.
+ </li>
+</ul>
+
+
+<h3 id="landscape-display">Landscape display</h3>
+
+<p>
+ A TV is always sideways: You can’t turn it, and there is no portrait orientation. Always design
+ your TV games to be displayed in landscape mode.
+</p>
+
+
+<h2 id="control">Input Devices</h2>
+
+<p>
+ TVs don't have touch interfaces, so it's even more important to get your controls right and make
+ sure that players find them intuitive and fun to use. The separation of controller from device
+ also introduces some other issues to pay attention to, like keeping track of multiple players'
+ controllers, and handling disconnects gracefully.
+</p>
+
+<h3 id="d-pad">D-pad</h3>
+
+<p>
+ Plan your control scheme around a directional pad (D-pad) control, since this control set is the
+ default for Android TV devices. The player needs to be able to use a D-Pad in all aspects of the
+ game–not just controlling core gameplay, but also navigating menus and ads. For this reason, you
+ should also ensure that your Android TV game does not refer to a touch interface: For example, an
+ Android TV game should not tell a player to <strong>Tap here to skip</strong>.
+</p>
+
+<p>
+ How you shape the player's interaction with the controller can be key to achieving a great user
+ experience:
+</p>
+
+<ul>
+ <li>
+ <strong>Communicate Controller Requirements up Front</strong> - Use your Play Store description
+ to communicate to the player any expectations about controllers. If a game is better suited to
+ a gamepad with a joystick than one with only a D-pad, make this fact clear. A player who uses
+ an ill-suited controller for a game is likely to have a subpar experience–and penalize your
+ game in the ratings.
+ </li>
+ <li>
+ <strong>Use Consistent Button Mapping</strong> - Intuitive and flexible button mapping is key
+ to a good user experience. For example, you can adhere to accepted custom by using the A button
+ to <code>Accept</code>, and the B button to <code>Cancel</code>. You can also offer flexibility
+ in the form of remappability. For more information on button mapping, see <a href=
+ "http://developer.android.com/training/game-controllers/controller-input.html">Handling
+ Controller Actions</a>.
+ </li>
+ <li>
+ <strong>Detect Controller Capabilities and Adjust Accordingly</strong> - Query the controller
+ about its capabilities in order to optimize the match between controller and game. For example,
+ you may intend for a player to steer an object by waving the controller in the air. If a
+ player's controller lacks accelerometer and gyroscope hardware, however, waving will not work.
+ When, however, your game queries the controller and discovers that motion detection is not
+ supported, it can switch over to an alternative, available control scheme. For more information
+ on querying controller capabilities, see <a href=
+ "http://developer.android.com/training/game-controllers/compatibility.html">Supporting
+ Controllers Across Android Versions</a>.
+ </li>
+</ul>
+
+
+<h3 id="back-button">Back-button behavior</h3>
+
+<p>
+ The Back button should never act as a toggle. For example, do not use it to both open and close a
+ menu. It should only navigate backward, breadcrumb-style, through the previous screens the player
+ has been on, for example: Game play &gt; Game pause screen &gt; Game main screen &gt; Android
+ home screen.
+</p>
+
+<p>
+ Since the Back button should only perform linear (backward) navigation, you may use the back
+ button to leave an in-game menu (opened by a different button) and return to gameplay. For more
+ information about design for navigation, see <a href=
+ "http://developer.android.com/design/patterns/navigation.html">Navigation with Back and Up</a>.
+ To learn about implementation, refer to <a href=
+ "http://developer.android.com/training/implementing-navigation/temporal.html">Providing Proper
+ Back Navigation</a>.
+</p>
+
+
+<h3 id="multiple-controllers">Handling multiple controllers</h3>
+
+<p>
+ When multiple players are playing a game, each with his or her own controller, it is important to
+ map each player-controller pair. For information on how to implement controller-number
+ identification, see <a href=
+ "http://developer.android.com/reference/android/view/InputDevice.html#getControllerNumber">Input
+ Devices</a>.
+</p>
+
+
+<h3 id="handle-disconnect">Handling disconnects</h3>
+
+<p>
+ When a controller is disconnected in the middle of gameplay, the game should pause, and a dialog
+ should appear prompting the disconnected player to reconnect his or her controller.
+</p>
+
+<p>
+ The dialog should also offer troubleshooting tips (for example, a pop-up dialog telling the
+ player to "Check your Bluetooth connection"). For more information on implementing input-device
+ support, see <a href=
+ "http://developer.android.com/training/game-controllers/controller-input.html">Handling Controller
+ Actions</a>. Specific information about Bluetooth connections is at <a href=
+ "http://developer.android.com/guide/topics/connectivity/bluetooth.html">Bluetooth</a>.
+</p>
+
+
+<h2 id="manifest">Manifest</h2>
+
+<p>
+ The Android TV launcher home screen displays games in a separate row from regular apps. The TV
+ framework uses the <code>android:isGame</code> manifest attribute to differentiate games from
+ non-game apps. Set this value to <code>true</code> in your game's app manifest, as shown in the
+ following code example:
+</p>
+
+<pre class="fragment">
+&lt;application&gt;
+ ...
+ &lt; meta-data android:name="isGame" android:value="true" &gt;
+ ...
+&lt;/application&gt;
+</pre>
+
+
+<h3 id="gamepad">Game Controllers</h3>
+
+<p>
+ Games controllers may not be available or active for users of a TV device. In order to properly
+ inform users that your game requires (or just supports) a game controller, you must include
+ entries in the app manifest. If your game requires a game controller, you must include the
+ following entry in your app manifest:
+</p>
+
+<pre>
+ &lt;uses-feature android:name="android.hardware.gamepad"/&gt;
+</pre>
+
+<p>
+ If your game uses, but does not require, a game controller, include the following feature
+ entry in your app manifest:
+</p>
+
+<pre>
+ &lt;uses-feature android:name="android.hardware.gamepad" android:required="false"/&gt;
+</pre>
+
+<p>For more information about manifest entries, see
+ <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">App Manifest</a>.
+</p>
+
+
+<h2 id="gpgs">Google Play Game Services</h2>
+
+<p>
+ If your game integrates Google Play Game Services, you should keep in mind a number of
+ considerations pertaining to achievements, sign-in, saving games, and multiplayer play.
+</p>
+
+
+<h3 id="achievements">Achievements</h3>
+
+<p>
+ Your game should include at least five (earnable) achievements. Only a user controlling gameplay
+ from a supported input device should be able to earn achievements. For more information on
+ achievements and how to implement them, see <a href=
+ "https://developers.google.com/games/services/android/achievements">Achievements in Android</a>.
+</p>
+
+
+<h3 id="sign-in">Sign-in</h3>
+
+<p>
+ Your game should attempt to sign the user in on launch. If the player declines sign-in several
+ times in a row, your game should stop asking. Learn more about sign-in at <a href=
+ "https://developers.google.com/games/services/training/signin">Implementing Sign-in on
+ Android</a>.
+</p>
+
+
+<h3 id="saving">Saving</h3>
+
+<p>
+ We highly recommend using Play Services <a href=
+ "https://developers.google.com/games/services/common/concepts/savedgames">Saved Games</a> to store
+ your game save. Your game should bind game saves to a specific Google account, so as to be
+ uniquely identifiable even across devices: Whether the player is using a handset or a TV, the
+ game should be able to pull the game-save information from the same user account.
+</p>
+
+<p>
+ You should also provide an option in your game's UI to allow the player to delete locally and
+ cloud-stored data. You might put the option in the game's <code>Settings</code> screen. For
+ specifics on implementing saved games using Play Services, see <a href=
+ "https://developers.google.com/games/services/android/savedgames">Saved Games in Android</a>.
+</p>
+
+
+<h3 id="multiplayer-ux">Multiplayer experience</h3>
+
+<p>
+ A game offering a multiplayer experience must allow at least two players to enter a room. For
+ further information on multiplayer games in Android, see the <a href=
+ "https://developers.google.com/games/services/android/realtimeMultiplayer">Real-time
+ Multiplayer</a> and <a href="">Turn-based Multiplayer</a> documentation on the Android developer
+ site.
+</p>
+
+
+<h2 id="web">Web</h2>
+
+<p>
+ We discourage enabling web browsing in games for Android TV. The television set is not
+ well-suited for browsing, either in terms of display or control scheme.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> You can use the {@link android.webkit.WebView} class for logins to
+ services like Google+ and Facebook.
+</p>
diff --git a/docs/html/training/tv/index.jd b/docs/html/training/tv/index.jd
index 54f7016..56667a9 100644
--- a/docs/html/training/tv/index.jd
+++ b/docs/html/training/tv/index.jd
@@ -1,59 +1,8 @@
-page.title=Designing for TV
-page.tags="input","screens"
-
-trainingnavtop=true
-startpage=true
+page.title=Building Apps for TV
+page.trainingcourse=true
@jd:body
-<div id="tb-wrapper">
-<div id="tb">
-
-<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
-<h2>Dependencies and prerequisites</h2>
-<ul>
- <li>Android 2.0 (API Level 5) or higher</li>
-</ul>
-
-</div>
-</div>
-
-<a class="notice-developers-video wide" href="http://www.youtube.com/watch?v=zsRnRLh-O34">
-<div>
- <h3>Video</h3>
- <p>DevBytes: Design for Large Displays - Part 1</p>
-</div>
-</a>
-
-<p>
- Smart TVs powered by Android bring your favorite Android apps to the best screen in your house.
- Thousands of apps in the Google Play Store are already optimized for TVs. This class shows how
- you can optimize your Android app for TVs, including how to build a layout that
- works great when the user is ten feet away and navigating with a remote control.
-</p>
-<h2>Lessons</h2>
-
-<dl>
- <dt><b><a href="optimizing-layouts-tv.html">Optimizing Layouts for TV</a></b></dt>
- <dd>Shows you how to optimize app layouts for TV screens, which have some unique characteristics such as:
- <ul>
- <li>permanent "landscape" mode</li>
- <li>high-resolution displays</li>
- <li>"10 foot UI" environment.</li>
- </ul>
- </dd>
-
- <dt><b><a href="optimizing-navigation-tv.html">Optimizing Navigation for TV</a></b></dt>
- <dd>Shows you how to design navigation for TVs, including:
- <ul>
- <li>handling D-pad navigation</li>
- <li>providing navigational feedback</li>
- <li>providing easily-accessible controls on the screen.</li>
- </ul>
- </dd>
- <dt><b><a href="unsupported-features-tv.html">Handling features not supported on TV</a></b></dt>
- <dd>Lists the hardware features that are usually not available on TVs. This lesson also shows you how to
- provide alternatives for missing features or check for missing features and disable code at run time.</dd>
-</dl>
+<p>These classes teach you how to build apps for TV devices.</p> \ No newline at end of file
diff --git a/docs/html/training/tv/optimizing-layouts-tv.jd b/docs/html/training/tv/optimizing-layouts-tv.jd
deleted file mode 100644
index a6db052..0000000
--- a/docs/html/training/tv/optimizing-layouts-tv.jd
+++ /dev/null
@@ -1,246 +0,0 @@
-page.title=Optimizing Layouts for TV
-parent.title=Designing for TV
-parent.link=index.html
-
-trainingnavtop=true
-next.title=Optimizing Navigation for TV
-next.link=optimizing-navigation-tv.html
-
-@jd:body
-
-<div id="tb-wrapper">
-<div id="tb">
-
-<h2>This lesson teaches you to</h2>
-<ol>
- <li><a href="#DesignLandscapeLayouts">Design Landscape Layouts</a></li>
- <li><a href="#MakeTextControlsEasyToSee">Make Text and Controls Easy to See</a></li>
- <li><a href="#DesignForLargeScreens">Design for High-Density Large Screens</a></li>
- <li><a href="#HandleLargeBitmaps">Design to Handle Large Bitmaps</a></li>
-</ol>
-
-<h2>You should also read</h2>
-<ul>
- <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
-</ul>
-
-</div>
-</div>
-
-<p>
-When your application is running on a television set, you should assume that the user is sitting about
-ten feet away from the screen. This user environment is referred to as the
-<a href="http://en.wikipedia.org/wiki/10-foot_user_interface">10-foot UI</a>. To provide your
-users with a usable and enjoyable experience, you should style and lay out your UI accordingly..
-</p>
-<p>
-This lesson shows you how to optimize layouts for TV by:
-</p>
-<ul>
- <li>Providing appropriate layout resources for landscape mode.</li>
- <li>Ensuring that text and controls are large enough to be visible from a distance.</li>
- <li>Providing high resolution bitmaps and icons for HD TV screens.</li>
-</ul>
-
-<h2 id="DesignLandscapeLayouts">Design Landscape Layouts</h2>
-
-<p>
-TV screens are always in landscape orientation. Follow these tips to build landscape layouts optimized for TV screens:
-</p>
-<ul>
- <li>Put on-screen navigational 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, by 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 allows the Android system to adjust the position of the views to the size, alignment,
- aspect ratio, and pixel density of the TV screen.</li>
- <li>Add sufficient margins between layout controls to avoid a cluttered UI.</li>
-</ul>
-
-<p>
-For example, the following layout is optimized for TV:
-</p>
-
-<img src="{@docRoot}images/training/panoramio-grid.png" />
-
-<p>
-In this layout, the controls are on the lefthand side. The UI is displayed within a
-{@link android.widget.GridView}, which is well-suited to landscape orientation.
-In this layout both GridView and Fragment have the width and height set
-dynamically, so they can adjust to the screen resolution. Controls are added to the left side Fragment programatically at runtime.
-The layout file for this UI is {@code res/layout-land-large/photogrid_tv.xml}.
-(This layout file is placed in {@code layout-land-large} because TVs have large screens with landscape orientation. For details refer to
-<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.)</p>
-
-res/layout-land-large/photogrid_tv.xml
-<pre>
-&lt;RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" &gt;
-
- &lt;fragment
- android:id="@+id/leftsidecontrols"
- android:layout_width="0dip"
- android:layout_marginLeft="5dip"
- android:layout_height="match_parent" /&gt;
-
- &lt;GridView
- android:id="@+id/gridview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" /&gt;
-
-&lt;/RelativeLayout>
-</pre>
-
-<p>
-To set up action bar items on the left side of the screen, you can also include the <a
-href="http://code.google.com/p/googletv-android-samples/source/browse/#git%2FLeftNavBarLibrary">
-Left navigation bar library</a> in your application to set up action items on the left side
-of the screen, instead of creating a custom Fragment to add controls:
-</p>
-
-<pre>
-LeftNavBar bar = (LeftNavBarService.instance()).getLeftNavBar(this);
-</pre>
-
-<p>
-When you have an activity in which the content scrolls vertically, always use a left navigation bar;
-otherwise, your users have to scroll to the top of the content to switch between the content view and
-the ActionBar. Look at the
-<a href="http://code.google.com/p/googletv-android-samples/source/browse/#git%2FLeftNavBarDemo">
-Left navigation bar sample app</a> to see how to simple it is to include the left navigation bar in your app.
-</p>
-
-<h2 id="MakeTextControlsEasyToSee">Make Text and Controls Easy to See</h2>
-<p>
-The text and controls in a TV application's UI 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 use anti-aliasing to increase readability.</li>
- <li>Use Android's standard font sizes:
- <pre>
- &lt;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"/&gt;
- </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>
-<p>
-
-</p>
-
-<h2 id="DesignForLargeScreens">Design for High-Density Large Screens</h2>
-
-<p>
-The common HDTV display resolutions are 720p, 1080i, and 1080p. Design your UI for 1080p, and then
-allow the Android system to downscale your UI to 720p if necessary. In general, downscaling (removing pixels)
-does not degrade the UI (Notice that the converse is not true; you should avoid upscaling because it degrades
-UI quality).
-</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 apps for large screens see <a href="{@docRoot}training/multiscreen/index.html">
-Designing for multiple screens</a>.
-</p>
-
-<h2 id="HandleLargeBitmaps">Design to Handle Large Bitmaps</h2>
-
-<p>
-The Android system has a limited amount of memory, so downloading and storing high-resolution images can often
-cause out-of-memory errors in your app. To avoid this, 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 them and store them on the SD card for faster access.
- Never do network transactions on the application's UI thread.
- </li>
- <li>Scale down really large images to a more appropriate size as you download them; otherwise, downloading the image
- itself may cause an "Out of Memory" exception. Here is sample code that scales 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 helps reduce memory use. It 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> \ No newline at end of file
diff --git a/docs/html/training/tv/optimizing-navigation-tv.jd b/docs/html/training/tv/optimizing-navigation-tv.jd
deleted file mode 100644
index bb78258..0000000
--- a/docs/html/training/tv/optimizing-navigation-tv.jd
+++ /dev/null
@@ -1,206 +0,0 @@
-page.title=Optimizing Navigation for TV
-parent.title=Designing for TV
-parent.link=index.html
-
-trainingnavtop=true
-previous.title=Optimizing Layouts for TV
-previous.link=optimizing-layouts-tv.html
-next.title=Handling Features Not Supported on TV
-next.link=unsupported-features-tv.html
-
-@jd:body
-
-<div id="tb-wrapper">
-<div id="tb">
-
-<h2>This lesson teaches you to</h2>
-<ol>
- <li><a href="#HandleDpadNavigation">Handle D-pad Navigation</a></li>
- <li><a href="#HandleFocusSelection">Provide Clear Visual Indication for Focus and Selection</a></li>
- <li><a href="#DesignForEasyNavigation">Design for Easy Navigation</a></li>
-</ol>
-
-<h2>You should also read</h2>
-<ul>
- <li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a></li>
-</ul>
-
-</div>
-</div>
-
-<p>
-An important aspect of the user experience when operating a TV is the direct human interface: a remote control.
-As you optimize your Android application for TVs, you should pay special attention to how the user actually navigates
-around your application when using a remote control instead of a touchscreen.
-</p>
-<p>
-This lesson shows you how to optimize navigation for TV by:
-</p>
-
-<ul>
- <li>Ensuring all layout controls are D-pad navigable.</li>
- <li>Providing highly obvious feedback for UI navigation.</li>
- <li>Placing layout controls for easy access.</li>
-</ul>
-
-<h2 id="HandleDpadNavigation">Handle D-pad Navigation</h2>
-
-<p>
-On a TV, users navigate with controls on a TV remote, using either a D-pad or arrow keys.
-This limits movement to up, down, left, and right.
-To build a great TV-optimized app, you must provide a navigation scheme in which the user can
-quickly learn how to navigate your app using the remote.
-</p>
-
-<p>
-When you design navigation for D-pad, follow these guidelines:
-</p>
-
-<ul>
- <li>Ensure that the D-pad can navigate to all the visible controls on the screen.</li>
- <li>For scrolling lists with focus, D-pad up/down keys scroll the list and Enter key selects an item in the list. Ensure that users can
- select an element in the list and that the list still scrolls when an element is selected.</li>
- <li>Ensure that movement between controls is straightforward and predictable.</li>
-</ul>
-
-<p>
-Android usually handles navigation order between layout elements automatically, so you don't need to do anything extra. If the screen layout
-makes navigation difficult, or if you want users to move through the layout in a specific way, you can set up explicit navigation for your
-controls.
-For example, for an {@code android.widget.EditText}, to define the next control to receive focus, use:
-<pre>
-&lt;EditText android:id="@+id/LastNameField" android:nextFocusDown="@+id/FirstNameField"\&gt;
-</pre>
-The following table lists all of the available navigation attributes:
-</p>
-
-<table>
-<tr>
-<th>Attribute</th>
-<th>Function</th>
-</tr>
-<tr>
-<td>{@link android.R.attr#nextFocusDown}</td>
-<td>Defines the next view to receive focus when the user navigates down.</td>
-</tr>
-<tr>
-<td>{@link android.R.attr#nextFocusLeft}</td>
-<td>Defines the next view to receive focus when the user navigates left.</td>
-</tr>
-<tr>
-<td>{@link android.R.attr#nextFocusRight}</td>
-<td>Defines the next view to receive focus when the user navigates right.</td>
-</tr>
-<tr>
-<td>{@link android.R.attr#nextFocusUp}</td>
-<td>Defines the next view to receive focus when the user navigates up.</td>
-</tr>
-</table>
-
-<p>
-To use one of these explicit navigation attributes, set the value to the ID (android:id value) of another widget in the layout. You should set
-up the navigation order as a loop, so that the last control directs focus back to the first one.
-</p>
-
-<p>
-Note: You should only use these attributes to modify the navigation order if the default order that the system applies does not work well.
-</p>
-
-<h2 id="HandleFocusSelection">Provide Clear Visual Indication for Focus and Selection</h2>
-
-<p>
-Use appropriate color highlights for all navigable and selectable elements in the UI. This makes it easy for users to know whether the control
-is currently focused or selected when they navigate with a D-pad. Also, use uniform highlight scheme across your application.
-</p>
-
-<p>
-Android provides <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">Drawable State List Resources</a> to implement highlights
-for selected and focused controls. For example:
-</p>
-
-res/drawable/button.xml:
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
- &lt;item android:state_pressed="true"
- android:drawable="@drawable/button_pressed" /&gt; &lt;!-- pressed --&gt;
- &lt;item android:state_focused="true"
- android:drawable="@drawable/button_focused" /&gt; &lt;!-- focused --&gt;
- &lt;item android:state_hovered="true"
- android:drawable="@drawable/button_focused" /&gt; &lt;!-- hovered --&gt;
- &lt;item android:drawable="@drawable/button_normal" /&gt; &lt;!-- default --&gt;
-&lt;/selector&gt;
-</pre>
-
-<p>
-This layout XML applies the above state list drawable to a {@link android.widget.Button}:
-</p>
-<pre>
-&lt;Button
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:background="@drawable/button" /&gt;
-</pre>
-
-<p>
-Provide sufficient padding within the focusable and selectable controls so that the highlights around them are clearly visible.
-</p>
-
-<h2 id="DesignForEasyNavigation">Design for Easy Navigation</h2>
-
-<p>
-Users should be able to navigate to any UI control with a couple of D-pad clicks. Navigation should be easy and intuitive to
-understand. For any non-intuitive actions, provide users with written help, using a dialog triggered by a help button or action bar icon.
-</p>
-
-<p>
-Predict the next screen that the user will want to navigate to and provide one click navigation to it. If the current screen UI is very sparse,
-consider making it a multi pane screen. Use fragments for making multi-pane screens. For example, consider the multi-pane UI below with continent names
-on the left and list of cool places in each continent on the right.
-</p>
-
-<img src="{@docRoot}images/training/cool-places.png" alt="" />
-
-<p>
-The above UI consists of three Fragments - <code>left_side_action_controls</code>, <code>continents</code> and
-<code>places</code> - as shown in its layout
-xml file below. Such multi-pane UIs make D-pad navigation easier and make good use of the horizontal screen space for
-TVs.
-</p>
-res/layout/cool_places.xml
-<pre>
-&lt;LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- &gt;
- &lt;fragment
- android:id="@+id/left_side_action_controls"
- android:layout_width="0px"
- android:layout_height="match_parent"
- android:layout_marginLeft="10dip"
- android:layout_weight="0.2"/&gt;
- &lt;fragment
- android:id="@+id/continents"
- android:layout_width="0px"
- android:layout_height="match_parent"
- android:layout_marginLeft="10dip"
- android:layout_weight="0.2"/&gt;
-
- &lt;fragment
- android:id="@+id/places"
- android:layout_width="0px"
- android:layout_height="match_parent"
- android:layout_marginLeft="10dip"
- android:layout_weight="0.6"/&gt;
-
-&lt;/LinearLayout&gt;
-</pre>
-
-<p>
-Also, notice in the UI layout above action controls are on the left hand side of a vertically scrolling list to make
-them easily accessible using D-pad.
-In general, for layouts with horizontally scrolling components, place action controls on left or right hand side and
-vice versa for vertically scrolling components.
-</p>
-
diff --git a/docs/html/training/tv/playback/browse.jd b/docs/html/training/tv/playback/browse.jd
new file mode 100644
index 0000000..9b25166
--- /dev/null
+++ b/docs/html/training/tv/playback/browse.jd
@@ -0,0 +1,230 @@
+page.title=Creating a Catalog Browser
+page.tags="browsefragment","presenter","backgroundmanager"
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#layout">Create a Media Browse Layout</a></li>
+ <li><a href="#lists">Display Media Lists</a></li>
+ <li><a href="#background">Update the Background</a></li>
+ </ol>
+
+</div>
+</div>
+
+<p>
+ Media apps that run on TV need to allow users to browse its content offerings, make a
+ selection, and start playing content. The content browsing experience for apps of this type
+ should be simple and intuitive, as well as visually pleasing and engaging.
+</p>
+
+<p>
+ This lesson discusses how to use the classes provided by the <a href=
+ "{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback support library</a> to
+ implement a user interface for browsing music or videos from your app's media catalog.
+</p>
+
+
+<h2 id="layout">Create a Media Browse Layout</h2>
+
+<p>
+ The {@link android.support.v17.leanback.app.BrowseFragment} class in the leanback library
+ allows you to create a primary layout for browsing categories and rows of media items with a
+ minimum of code. The following example shows how to create a layout that contains a {@link
+ android.support.v17.leanback.app.BrowseFragment}:
+</p>
+
+<pre>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width=&quot;match_parent&quot;
+ android:layout_height=&quot;match_parent&quot;
+ android:orientation=&quot;vertical&quot;
+ &gt;
+
+ &lt;fragment
+ <strong>android:name="android.support.v17.leanback.app.BrowseFragment"</strong>
+ android:id=&quot;@+id/browse_fragment&quot;
+ android:layout_width=&quot;match_parent&quot;
+ android:layout_height=&quot;match_parent&quot;
+ /&gt;
+&lt;/LinearLayout&gt;
+</pre>
+
+<p>
+ In order to work with this layout in an activity, retrieve the {@link
+ android.support.v17.leanback.app.BrowseFragment} element from the layout. Use the methods in this
+ class to set display parameters such as the icon, title, and whether category headers are enabled.
+ The following code sample demonstrates how to set the layout parameters for a {@link
+ android.support.v17.leanback.app.BrowseFragment} in a layout:
+</p>
+
+<pre>
+public class BrowseMediaActivity extends Activity {
+
+ public static final String TAG ="BrowseActivity";
+
+ protected BrowseFragment mBrowseFragment;
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.browse_fragment);
+
+ final FragmentManager fragmentManager = getFragmentManager();
+ <strong>mBrowseFragment = (BrowseFragment) fragmentManager.findFragmentById(
+ R.id.browse_fragment);</strong>
+
+ // Set display parameters for the BrowseFragment
+ mBrowseFragment.setHeadersState(BrowseFragment.HEADERS_ENABLED);
+ mBrowseFragment.setTitle(getString(R.string.app_name));
+ mBrowseFragment.setBadgeDrawable(getResources().getDrawable(
+ R.drawable.ic_launcher));
+ mBrowseFragment.setBrowseParams(params);
+
+ }
+}
+</pre>
+
+
+<h2 id="lists">Displaying Media Lists</h2>
+
+<p>
+ The {@link android.support.v17.leanback.app.BrowseFragment} allows you to define and display
+ browsable media content categories and media items from a media catalog using adapters and
+ presenters. Adapters enable you to connect to local or online data sources that contain your
+ media catalog information. Presenters hold data about media items and provide layout information
+ for displaying an item on screen.
+</p>
+
+<p>
+ The following example code shows an implementation of a {@link
+ android.support.v17.leanback.widget.Presenter} for displaying string data:
+</p>
+
+<pre>
+public class StringPresenter extends Presenter {
+ private static final String TAG = "StringPresenter";
+
+ public ViewHolder onCreateViewHolder(ViewGroup parent) {
+ TextView textView = new TextView(parent.getContext());
+ textView.setFocusable(true);
+ textView.setFocusableInTouchMode(true);
+ textView.setBackground(
+ parent.getContext().getResources().getDrawable(R.drawable.text_bg));
+ return new ViewHolder(textView);
+ }
+
+ public void onBindViewHolder(ViewHolder viewHolder, Object item) {
+ ((TextView) viewHolder.view).setText(item.toString());
+ }
+
+ public void onUnbindViewHolder(ViewHolder viewHolder) {
+ // no op
+ }
+}
+</pre>
+
+<p>
+ Once you have constructed a presenter class for your media items, you can build and attach an
+ adapter to the {@link android.support.v17.leanback.app.BrowseFragment} to display those items on
+ screen for browsing by the user. The following example code demonstrates how to construct an
+ adapter to display categories and items in those categories using the {@code StringPresenter}
+ class shown in the previous code example:
+</p>
+
+<pre>
+private ArrayObjectAdapter mRowsAdapter;
+private static final int NUM_ROWS = 4;
+
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ ...
+
+ buildRowsAdapter();
+}
+
+private void buildRowsAdapter() {
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+
+ for (int i = 0; i &lt; NUM_ROWS; ++i) {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
+ new StringPresenter());
+ listRowAdapter.add("Media Item 1");
+ listRowAdapter.add("Media Item 2");
+ listRowAdapter.add("Media Item 3");
+ HeaderItem header = new HeaderItem(i, "Category " + i, null);
+ mRowsAdapter.add(new ListRow(header, listRowAdapter));
+ }
+
+ mBrowseFragment.setAdapter(mRowsAdapter);
+}
+</pre>
+
+<p>
+ This example shows a static implementation of the adapters. A typical media browsing application
+ uses data from an online database or web service. For an example of a browsing application that
+ uses data retrieved from the web, see the
+ <a href="http://github.com/googlesamples/androidtv-leanback">Android TV</a> sample app.
+</p>
+
+<h2 id="background">Update the Background</h2>
+
+<p>
+ In order to add visual interest to a media-browsing app on TV, you can update the background
+ image as users browse through content. This technique can make interaction with your app feel
+ more cinematic and enjoyable for users.
+</p>
+
+<p>
+ The Leanback support library provides a {@link android.support.v17.leanback.app.BackgroundManager}
+ class for changing the background of your TV app activity. The following example shows how to
+ create a simple method for updating the background within your TV app activity:
+</p>
+
+<pre>
+protected void updateBackground(Drawable drawable) {
+ BackgroundManager.getInstance(this).setDrawable(drawable);
+}
+</pre>
+
+<p>
+ Many of the existing media-browse apps automatically update the background as the user navigates
+ through media listings. In order to do this, you can set up a selection listener to automatically
+ update the background based on the user's current selection. The following example shows you how
+ to set up an {@link android.support.v17.leanback.widget.OnItemViewSelectedListener} class to
+ catch selection events and update the background:
+</p>
+
+<pre>
+protected void clearBackground() {
+ BackgroundManager.getInstance(this).setDrawable(mDefaultBackground);
+}
+
+protected OnItemViewSelectedListener getDefaultItemViewSelectedListener() {
+ return new OnItemViewSelectedListener() {
+ &#64;Override
+ public void onItemSelected(Object item, Row row) {
+ if (item instanceof Movie ) {
+ URI uri = ((Movie)item).getBackdropURI();
+ updateBackground(uri);
+ } else {
+ clearBackground();
+ }
+ }
+ };
+}
+</pre>
+
+<p class="note">
+ <strong>Note:</strong> The implementation above is a simple example shown for purposes of
+ illustration. When creating this function in your own app, you should consider running the
+ background update action in a separate thread for better performance. In addition, if you are
+ planning on updating the background in response to users scrolling through items, consider adding
+ a time to delay a background image update until the user settles on an item. This technique avoids
+ excessive background image updates.
+</p>
diff --git a/docs/html/training/tv/playback/details.jd b/docs/html/training/tv/playback/details.jd
new file mode 100644
index 0000000..6391a49
--- /dev/null
+++ b/docs/html/training/tv/playback/details.jd
@@ -0,0 +1,247 @@
+page.title=Building a Details View
+page.tags="detailsfragment"
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#details-presenter">Build a Details Presenter</a></li>
+ <li><a href="#details-fragment">Extend the Details Fragment</a>
+ <li><a href="#activity">Create a Details Activity</a></li>
+ <li><a href="#item-listener">Define a Listener for Clicked Items</a></li>
+ </ol>
+</div>
+</div>
+
+<p>
+ The media browsing interface classes provided by the <a href=
+ "{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback support library</a>
+ include classes for displaying additional information about a media item, such as a description
+ or reviews, and for taking action on that item, such as purchasing it or playing its content.
+</p>
+
+<p>
+ This lesson discusses how to create a presenter class for media item details, and how to extend
+ the {@link android.support.v17.leanback.app.DetailsFragment} class to implement a details view
+ for a media item when it is selected by a user.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> The implementation example shown here uses an additional activity to
+ contain the {@link android.support.v17.leanback.app.DetailsFragment}. However, it is possible to
+ avoid creating a second activity by replacing the current {@link
+ android.support.v17.leanback.app.BrowseFragment} with a {@link
+ android.support.v17.leanback.app.DetailsFragment} within the <em>same</em> activity using
+ fragment transactions. For more information on using fragment transactions, see the <a href=
+ "{@docRoot}training/basics/fragments/fragment-ui.html#Replace">Building a Dynamic UI with
+ Fragments</a> training.
+</p>
+
+
+<h2 id="details-presenter">Build a Details Presenter</h2>
+
+<p>
+ In the media browsing framework provided by the leanback library, you use presenter
+ objects to control the display of data on screen, including media item details. The framework
+ provides the {@link android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter}
+ class for this purpose, which is a nearly complete implementation of the presenter for media item
+ details. All you have to do is implement the {@link
+ android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter#onBindDescription
+ onBindDescription()} method to bind the view fields to your data objects, as shown in the
+ following code sample:
+</p>
+
+<pre>
+public class DetailsDescriptionPresenter
+ extends AbstractDetailsDescriptionPresenter {
+
+ &#64;Override
+ protected void onBindDescription(ViewHolder viewHolder, Object itemData) {
+ MyMediaItemDetails details = (MyMediaItemDetails) itemData;
+ // In a production app, the itemData object contains the information
+ // needed to display details for the media item:
+ // viewHolder.getTitle().setText(details.getShortTitle());
+
+ // Here we provide static data for testing purposes:
+ viewHolder.getTitle().setText(itemData.toString());
+ viewHolder.getSubtitle().setText("2014 Drama TV-14");
+ viewHolder.getBody().setText("Lorem ipsum dolor sit amet, consectetur "
+ + "adipisicing elit, sed do eiusmod tempor incididunt ut labore "
+ + " et dolore magna aliqua. Ut enim ad minim veniam, quis "
+ + "nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
+ + "commodo consequat.");
+ }
+}
+</pre>
+
+
+<h2 id="details-fragment">Extend the Details Fragment</h2>
+
+<p>
+ When using the {@link android.support.v17.leanback.app.DetailsFragment} class for displaying
+ your media item details, extend that class to provide additional content such as a preview
+ image and actions for the media item. You can also provide additional content, such as a list of
+ related media items.
+</p>
+
+<p>
+ The following example code demonstrates how to use the presenter class shown in the
+ previous section, to add a preview image and actions for the media item being viewed. This example
+ also shows the addition of a related media items row, which appears below the details listing.
+</p>
+
+<pre>
+public class MediaItemDetailsFragment extends DetailsFragment {
+ private static final String TAG = "MediaItemDetailsFragment";
+ private ArrayObjectAdapter mRowsAdapter;
+
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.i(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+
+ buildDetails();
+ }
+
+ private void buildDetails() {
+ ClassPresenterSelector selector = new ClassPresenterSelector();
+ // Attach your media item details presenter to the row presenter:
+ DetailsOverviewRowPresenter rowPresenter =
+ new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
+
+ selector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
+ selector.addClassPresenter(ListRow.class,
+ new ListRowPresenter());
+ mRowsAdapter = new ArrayObjectAdapter(selector);
+
+ Resources res = getActivity().getResources();
+ DetailsOverviewRow detailsOverview = new DetailsOverviewRow(
+ "Media Item Details");
+
+ // Add images and action buttons to the details view
+ detailsOverview.setImageDrawable(res.getDrawable(R.drawable.jelly_beans));
+ detailsOverview.addAction(new Action(1, "Buy $9.99"));
+ detailsOverview.addAction(new Action(2, "Rent $2.99"));
+ mRowsAdapter.add(detailsOverview);
+
+ // Add a Related items row
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
+ new StringPresenter());
+ listRowAdapter.add("Media Item 1");
+ listRowAdapter.add("Media Item 2");
+ listRowAdapter.add("Media Item 3");
+ HeaderItem header = new HeaderItem(0, "Related Items", null);
+ mRowsAdapter.add(new ListRow(header, listRowAdapter));
+
+ setAdapter(mRowsAdapter);
+ }
+}
+</pre>
+
+
+<h3 id="activity">Create a Details Activity</h3>
+
+<p>
+ Fragments such as the {@link android.support.v17.leanback.app.DetailsFragment} must be contained
+ within an activity in order to be used for display. Creating an activity for your details view,
+ separate from the browse activity, enables you to invoke your details view using an
+ {@link android.content.Intent}. This
+ section explains how to build an activity to contain your implementation of the detail view for
+ your media items.
+</p>
+
+<p>
+ Start creating the details activity by building a layout that references your implementation of
+ the {@link android.support.v17.leanback.app.DetailsFragment}:
+</p>
+
+<pre>
+&lt;!-- file: res/layout/details.xml --&gt;
+
+&lt;fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ <strong>android:name="com.example.android.mediabrowser.MediaItemDetailsFragment"</strong>
+ android:id="&#64;+id/details_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+/&gt;
+</pre>
+
+<p>
+ Next, create an activity class that uses the layout shown in the previous code example:
+</p>
+
+<pre>
+public class DetailsActivity extends Activity
+{
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ <strong>setContentView(R.layout.details);</strong>
+ }
+}
+</pre>
+
+<p>
+ Finally, add this new activity to the manifest. Remember to apply the Leanback theme to ensure
+ that the user interface is consistent with the media browse activity:
+</p>
+
+<pre>
+&lt;application&gt;
+ ...
+
+ &lt;activity android:name=".DetailsActivity"
+ android:exported="true"
+ <strong>android:theme="@style/Theme.Leanback"/&gt;</strong>
+
+&lt;/application&gt;
+</pre>
+
+
+<h3 id="item-listener">Define a Listener for Clicked Items</h3>
+
+<p>
+ After you have implemented the {@link android.support.v17.leanback.app.DetailsFragment},
+ modify your main media browsing view to move to your details view when a user clicks on a media
+ item. In order to enable this behavior, add an
+ {@link android.support.v17.leanback.widget.OnItemViewClickedListener} object to the
+ {@link android.support.v17.leanback.app.BrowseFragment} that fires an intent to start the item
+ details activity.
+</p>
+
+<p>
+ The following example shows how to implement a listener to start the details view when a user
+ clicks a media item in the main media browsing activity:
+</p>
+
+<pre>
+public class BrowseMediaActivity extends Activity {
+ ...
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ ...
+
+ // create the media item rows
+ buildRowsAdapter();
+
+ // add a listener for selected items
+ mBrowseFragment.OnItemViewClickedListener(
+ new OnItemViewClickedListener() {
+ &#64;Override
+ public void onItemClicked(Object item, Row row) {
+ System.out.println("Media Item clicked: " + item.toString());
+ Intent intent = new Intent(BrowseMediaActivity.this,
+ DetailsActivity.class);
+ // pass the item information
+ intent.getExtras().putLong("id", item.getId());
+ startActivity(intent);
+ }
+ });
+ }
+}
+</pre>
diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd
new file mode 100644
index 0000000..118fc6c
--- /dev/null
+++ b/docs/html/training/tv/playback/index.jd
@@ -0,0 +1,52 @@
+page.title=Building TV Playback Apps
+page.tags="leanback"
+
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+ <ul>
+ <li>Android 5.0 (API level 21) or higher</li>
+ </ul>
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}design/tv/index.html">
+ Design for TV</a></li>
+ </ul>
+</div>
+</div>
+
+<p>
+ Browsing and playing media files is frequently part of the user experience provided by a TV app.
+ Building such an experience from scratch, while making sure that it is fast, fluid, and attractive
+ can be quite challenging. Whether your app provides access to a small or large media catalog,
+ it is important to allow users to quickly browse options and get to the content they want.
+</p>
+
+<p>
+ The Android framework provides classes for building user interfaces for these types of apps with
+ the <a href="{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback support
+ library</a>. This library provides a framework of classes for creating an efficient and familiar
+ interface for browsing and playing media files with minimal coding. The classes are designed
+ be extended and customized so you can create an experience that is unique to your app.
+</p>
+
+<p>This class shows you how to build a TV app for browsing and playing media content using the Leanback
+ support libraries for TV.</p>
+
+<h2>Topics</h2>
+
+<dl>
+ <dt><b><a href="browse.html">Creating a Catalog Browser</a></b></dt>
+ <dd>Learn how to use the Leanback support library to build a browsing interface for media
+ catalogs.</dd>
+
+ <dt><b><a href="details.html">Building a Details View</a></b></dt>
+ <dd>Learn how to use the Leanback support library to build a details page for media items.</dd>
+
+ <dt><b><a href="now-playing.html">Displaying a Now Playing Card</a></b></dt>
+ <dd>Learn how to use a MediaSession to display a Now Playing card on the home screen.</dd>
+</dl>
diff --git a/docs/html/training/tv/playback/now-playing.jd b/docs/html/training/tv/playback/now-playing.jd
new file mode 100644
index 0000000..b64beb0
--- /dev/null
+++ b/docs/html/training/tv/playback/now-playing.jd
@@ -0,0 +1,167 @@
+page.title=Displaying a Now Playing Card
+page.tags="nowplaying","mediasession"
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#session">Start a Media Session</a></li>
+ <li><a href="#card">Display a Now Playing Card</a></li>
+ <li><a href="#state">Update the Playback State</a></li>
+ <li><a href="#respond">Respond to User Action</a></li>
+ </ol>
+
+</div>
+</div>
+
+<p>TV apps may allow users to play music or other media in the background while using other
+applications. If your app allows this type of use, it must must
+provide a means for the user to return to the app to pause the music or switch to a new song. The
+Android framework enables TV apps to do this by displaying a <em>Now Playing</em> card on the home
+screen in the recommendations row.</p>
+
+<p>The Now Playing card is a system artifact that displays on the
+home screen in the recommendations row for an active media session. It includes the media metadata
+such as the album art, title, and app icon. When the user selects it, the system opens the the app
+that owns the session.</p>
+
+<p>This lesson shows how to use the {@link android.media.session.MediaSession} class to implement
+the Now Playing card.</p>
+
+<h2 id="session">Start a Media Session</h2>
+
+<p>A playback app can run as an <a href="{@docRoot}guide/components/activities">activity</a> or
+as a <a href="{@docRoot}guide/components/services">service</a>. The service is required for
+background playback because it can continue to play media even after the activity that launched it
+has been destroyed. For this discussion, the media playback app is assumed to be running in a
+{@link android.service.media.MediaBrowserService}.</p>
+
+<p>In your service's {@link android.service.media.MediaBrowserService#onCreate() onCreate()}
+method, create a new {@link android.media.session.MediaSession#MediaSession(android.content.Context, java.lang.String) MediaSession},
+set the callback and flags appropriate to a media app, and set the session token for the
+{@link android.service.media.MediaBrowserService}.</p>
+
+<pre>
+mSession = new MediaSession(this, "MusicService");
+mSession.setCallback(new MediaSessionCallback());
+mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
+ MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
+
+// for the MediaBrowserService
+setSessionToken(mSession.getSessionToken());
+</pre>
+
+<p class="note"<strong>Note:</strong> The Now Playing card will display only for a media session with
+the {@link android.media.session.MediaSession#FLAG_HANDLES_TRANSPORT_CONTROLS} flag set.</p>
+
+<h2 id="card">Display a Now Playing Card</h2>
+
+<p>The Now Playing card shows up after {@link android.media.session.MediaSession#setActive(boolean) setActive(true)}
+is called, if the session is the highest priority session in the system. Also, note that your app
+must request the audio focus, as described in <a href="{@docRoot}training/managing-audio/audio-focus">
+Managing Audio Focus</a>.</p>
+
+<pre>
+private void handlePlayRequest() {
+
+ tryToGetAudioFocus();
+
+ if (!mSession.isActive()) {
+ mSession.setActive(true);
+ }
+...
+</pre>
+
+<p>The card is removed from the home screen when {@link android.media.session.MediaSession#setActive(boolean) setActive(false)}
+is called or if another app initiates media playback. You may want to remove the card from the home
+screen some time after playback is paused, depending on how long you want to keep the card up,
+usually 5 to 30 minutes.</p>
+
+<h2 id="state">Update the Playback State</h2>
+
+<p>As with any media app, update the playback state in the {@link android.media.session.MediaSession}
+so that the card can display the current metadata, as shown in the following example:</p>
+
+<pre>
+private void updatePlaybackState() {
+ long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN;
+ if (mMediaPlayer != null &amp;&amp; mMediaPlayer.isPlaying()) {
+ position = mMediaPlayer.getCurrentPosition();
+ }
+ PlaybackState.Builder stateBuilder = new PlaybackState.Builder()
+ .setActions(getAvailableActions());
+ stateBuilder.setState(mState, position, 1.0f);
+ mSession.setPlaybackState(stateBuilder.build());
+}
+private long getAvailableActions() {
+ long actions = PlaybackState.ACTION_PLAY |
+ PlaybackState.ACTION_PLAY_FROM_MEDIA_ID |
+ PlaybackState.ACTION_PLAY_FROM_SEARCH;
+ if (mPlayingQueue == null || mPlayingQueue.isEmpty()) {
+ return actions;
+ }
+ if (mState == PlaybackState.STATE_PLAYING) {
+ actions |= PlaybackState.ACTION_PAUSE;
+ }
+ if (mCurrentIndexOnQueue &gt; 0) {
+ actions |= PlaybackState.ACTION_SKIP_TO_PREVIOUS;
+ }
+ if (mCurrentIndexOnQueue &lt; mPlayingQueue.size() - 1) {
+ actions |= PlaybackState.ACTION_SKIP_TO_NEXT;
+ }
+ return actions;
+}
+</pre>
+
+<h2 id="metadata">Display the Media Metadata</h2>
+
+<p>For the track currently playing, set the {@link android.media.MediaMetadata} with the
+{@link android.media.session.MediaSession#setMetadata(android.media.MediaMetadata) setMetadata()}
+method. This method of the media session object lets you provide information to the Now Playing card
+about the track such as the title, subtitle, and various icons. The following example assumes your
+track's data is stored in a custom data class, {@code MediaData}.</p>
+
+<pre>
+private void updateMetadata(MediaData myData) {
+ MediaMetadata.Builder metadataBuilder = new MediaMetadata.Builder();
+ // To provide most control over how an item is displayed set the
+ // display fields in the metadata
+ metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE,
+ myData.displayTitle);
+ metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE,
+ myData.displaySubtitle);
+ metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI,
+ myData.artUri);
+ // And at minimum the title and artist for legacy support
+ metadataBuilder.putString(MediaMetadata.METADATA_KEY_TITLE,
+ myData.title);
+ metadataBuilder.putString(MediaMetadata.METADATA_KEY_ARTIST,
+ myData.artist);
+ // A small bitmap for the artwork is also recommended
+ metadataBuilder.putString(MediaMetadata.METADATA_KEY_ART,
+ myData.artBitmap);
+ // Add any other fields you have for your data as well
+ mSession.setMetadata(metadataBuilder.build());
+}
+</pre>
+
+<h2 id="respond">Respond to User Action</h2>
+
+<p>When the user selects the Now Playing card, the system opens the app that owns the session.
+If your app provides a {@link android.app.PendingIntent} to pass to
+{@link android.media.session.MediaSession#setSessionActivity(android.app.PendingIntent) setSessionActivity()},
+the system launches the activity you specify, as demonstrated below. If not, the default system
+intent opens. The activity you specify must provide playback controls that allow users to pause or
+stop playback.</p>
+
+<pre>
+Intent intent = new Intent(mContext, MyActivity.class);
+ PendingIntent pi = PendingIntent.getActivity(context, 99 /*request code*/,
+ intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ mSession.setSessionActivity(pi);
+</pre>
+
diff --git a/docs/html/training/tv/start/hardware.jd b/docs/html/training/tv/start/hardware.jd
new file mode 100644
index 0000000..33d396b
--- /dev/null
+++ b/docs/html/training/tv/start/hardware.jd
@@ -0,0 +1,361 @@
+page.title=Handling TV Hardware
+page.tags="unsupported"
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you how to</h2>
+ <ol>
+ <li><a href="#runtime-check">Check for a TV Device</a>
+ <li><a href="#handle-features">Handle Unsupported Hardware Features</a></li>
+ <li><a href="#controllers">Manage Hardware Controllers</a>
+ </li>
+ </ol>
+</div>
+</div>
+
+<p>
+ TV hardware is substantially different from other Android devices. TVs do not
+ include some of the hardware features found on other Android devices, such as touch screens,
+ cameras, and GPS receivers. TVs are also completely dependent on secondary hardware devices.
+ In order for users to interact with TV apps, they must use a remote control or game pad. When
+ you build an app for TV, you must carefully consider the hardware limitations and requirements of
+ operating on TV hardware.
+</p>
+
+<p>
+ This lesson discusses how to check if your app is running on a TV, how to handle unsupported
+ hardware features, and discusses the requirements for handling controllers for TV devices.
+</p>
+
+
+<h2 id="runtime-check">Check for a TV Device</h2>
+
+<p>
+ If you are building an app that operates both on TV devices and other devices, you may need to
+ check what kind of device your app is running on and adjust the operation of your app. For
+ instance, if you have an app that can be started through an {@link android.content.Intent}, your
+ application should check the device properties to determine if it should start a TV-oriented
+ activity or a phone activity.
+</p>
+
+<p>
+ The recommended way to determine if your app is running on a TV device is to use the {@link
+ android.app.UiModeManager#getCurrentModeType UiModeManager.getCurrentModeType()} method to check
+ if the device is running in television mode. The following example code shows you how to check if
+ your app is running on a TV device:
+</p>
+
+<pre>
+public static final String TAG = "DeviceTypeRuntimeCheck";
+
+UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
+if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
+ Log.d(TAG, "Running on a TV Device")
+} else {
+ Log.d(TAG, "Running on a non-TV Device")
+}
+</pre>
+
+
+<h2 id="handle-features">Handle Unsupported Hardware Features</h2>
+
+<p>
+ Depending on the design and functionality of your app, you may be able to work around certain
+ hardware features being unavailable. This section discusses what hardware features are typically
+ not available for TV, how to detect missing hardware features, and suggests alternatives to
+ using these features.
+</p>
+
+
+<h3 id="unsupported-features">Unsupported TV hardware features</h3>
+
+<p>
+ TVs have a different purpose from other devices, and so they do not have hardware features that
+ other Android-powered devices often have. For this reason, the Android system does not support
+ the following features for a TV device:
+</p>
+
+<table>
+ <tr>
+ <th>Hardware</th>
+ <th>Android feature descriptor</th>
+ </tr>
+ <tr>
+ <td>Touchscreen</td>
+ <td>android.hardware.touchscreen</td>
+ </tr>
+ <tr>
+ <td>Telephony</td>
+ <td>android.hardware.telephony</td>
+ </tr>
+ <tr>
+ <td>Camera</td>
+ <td>android.hardware.camera</td>
+ </tr>
+ <tr>
+ <td>Near Field Communications (NFC)</td>
+ <td>android.hardware.nfc</td>
+ </tr>
+ <tr>
+ <td>GPS</td>
+ <td>android.hardware.location.gps</td>
+ </tr>
+ <tr>
+ <td>Microphone</td>
+ <td>android.hardware.microphone</td>
+ </tr>
+</table>
+
+
+<h3 id="declare-hardware-requirements">Declaring hardware requirements for TV</h3>
+
+<p>
+ Android apps can declare hardware feature requirements in the app manifest to ensure that they do
+ not get installed on devices that do not provide those features. If you are extending an existing
+ app for use on TV, closely review your app's manifest for any hardware requirement
+ declarations that might prevent it from being installed on a TV device.
+</p>
+
+<p>
+ If your app uses hardware features (such as a touchscreen or camera) that are not available on
+ TV, but can operate without the use of those features, modify your app's manifest to
+ indicate that these features are not required by your app. The following manifest code snippet
+ demonstrates how to declare that your app does not require hardware features which are unavailable
+ on TV devices, even though your app may use these features on non-TV devices:
+</p>
+
+<pre>
+&lt;uses-feature android:name="android.hardware.touchscreen"
+ android:required="false"/&gt;
+&lt;uses-feature android:name="android.hardware.telephony"
+ android:required="false"/&gt;
+&lt;uses-feature android:name="android.hardware.camera"
+ android:required="false"/&gt;
+&lt;uses-feature android:name="android.hardware.nfc"
+ android:required="false"/&gt;
+&lt;uses-feature android:name="android.hardware.gps"
+ android:required="false"/&gt;
+&lt;uses-feature android:name="android.hardware.microphone"
+ android:required="false"/&gt;
+</pre>
+
+<p class="caution">
+ <strong>Caution:</strong> Declaring an unavailable hardware feature as required by setting its
+ value to {@code true} in your app manifest prevents your app from being installed on TV
+ devices or appearing in the Android TV home screen launcher.
+</p>
+
+<p class="caution">
+ <strong>Caution:</strong> Some <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">{@code uses-permission}</a> manifest declarations <em>imply hardware use</em>, which can also
+ prevent your app from being installed and used on TV devices. For example, requesting the
+ {@link android.Manifest.permission#RECORD_AUDIO} permission in your app implies the
+ {@code android.hardware.microphone} hardware feature requirement. In which case, you must declare
+ the microphone feature as not required ({@code android:required="false"}) in your app manifest.
+ For a list of permission requests that imply a hardware feature requirement, see <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#permissions-features">
+ {@code uses-feature}</a> guide.
+</p>
+
+<p>
+ Once you decide to make hardware features optional for your app, you must check for the
+ availability of those features at runtime and then adjust your app's behavior. The next section
+ discusses how to check for hardware features and suggests some approaches for changing the
+ behavior of your app.
+</p>
+
+<p>
+ For more information on filtering and declaring features in the manifest, see the
+ <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code uses-feature}</a>
+ guide.
+</p>
+
+
+<h3 id="check-features">Checking for hardware features</h2>
+
+<p>
+ The Android framework can tell you if hardware features are not available on the device where
+ your app is running. Use the {@link android.content.pm.PackageManager#hasSystemFeature(String)}
+ method to check for specific features at runtime. This method takes a single string argument that
+ specifies the feature you want to check.
+</p>
+
+<p>The following code example demonstrates how to detect the availability of hardware features
+ at runtime:</p>
+
+<pre>
+// Check if the telephony hardware feature is available.
+if (getPackageManager().hasSystemFeature("android.hardware.telephony")) {
+ Log.d("HardwareFeatureTest", "Device can make phone calls");
+}
+
+// Check if android.hardware.touchscreen feature is available.
+if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) {
+ Log.d("HardwareFeatureTest", "Device has a touch screen.");
+}
+</pre>
+
+
+<h4 id="no-touchscreen">Touch screen</h4>
+
+<p>
+ Since most TVs do not have touch screens, Android does not support touch screen interaction for
+ TV devices. Furthermore, using a touch screen is not consistent with a viewing environment where
+ the user is seated 10 feet away from the display.
+</p>
+
+<p>
+ On TV devices, you should design your app to work with this interaction model by supporting
+ navigation using a directional pad (D-pad) on a TV remote control. For more information on
+ properly supporting navigation using TV-friendly controls, see
+ <a href="{@docRoot}training/tv/start/navigation.html">Creating TV Navigation</a>.
+</p>
+
+
+<h4 id="no-camera">Camera</h4>
+
+<p>
+ Although a TV typically does not have a camera, you can still provide a photography-related
+ app on a TV. For example, if you have an app that takes, views, and edits photos, you can
+ disable its picture-taking functionality for TVs and still allow users to view and even edit
+ photos. If you decide to enable your camera-related app to work on a TV, add the
+ following feature declaration your app manifest:
+</p>
+
+<pre>
+&lt;uses-feature android:name="android.hardware.camera" android:required="false" /&gt;
+</pre>
+
+<p>
+ If you enable your app to run without a camera, add code to your app
+ that detects if the camera feature is available and makes adjustments to the operation of your
+ app. The following code example demonstrates how to detect the presence of a camera:
+</p>
+
+<pre>
+// Check if the camera hardware feature is available.
+if (getPackageManager().hasSystemFeature("android.hardware.camera")) {
+ Log.d("Camera test", "Camera available!");
+} else {
+ Log.d("Camera test", "No camera available. View and edit features only.");
+}
+</pre>
+
+
+<h4 id="no-gps">GPS</h4>
+
+<p>
+ TVs are stationary, indoor devices, and do not have built-in global positioning system (GPS)
+ receivers. If your app uses location information, you can still allow users to search for
+ a location, or use a static location provider such as a zip code configured during the TV device
+ setup.
+</p>
+
+<pre>
+// Request a static location from the location manager
+LocationManager locationManager = (LocationManager) this.getSystemService(
+ Context.LOCATION_SERVICE);
+Location location = locationManager.getLastKnownLocation("static");
+
+// Attempt to get postal or zip code from the static location object
+Geocoder geocoder = new Geocoder(this);
+Address address = null;
+try {
+ address = geocoder.getFromLocation(location.getLatitude(),
+ location.getLongitude(), 1).get(0);
+ Log.d("Zip code", address.getPostalCode());
+
+} catch (IOException e) {
+ Log.e(TAG, "Geocoder error", e);
+}
+</pre>
+
+
+<h2 id="controllers">Handling Controllers</h2>
+
+<p>
+ TV devices require a secondary hardware device for interacting with apps, in the form of a basic
+ remote controller or game controller. This means that your app must support D-pad input. It also
+ means that your app may need to handle controllers going offline and input from more than one
+ type of controller.
+</p>
+
+
+<h3 id="d-pad-minimum">D-pad minimum controls</h3>
+
+<p>
+ The default controller for a TV device is a D-pad. In general, your app should be operable from a
+ remote controller that only has up, down, left, right, select, Back, and Home buttons. If your app
+ is a game that typically requires a game controller with additional controls, your app should
+ attempt to allow gameplay with these D-pad controls. In this case, your app should also warn the
+ user that
+ a controller is required and allow them to exit your game gracefully using the D-pad controller.
+ For more information about handling navigation with D-pad controller for TV devices, see
+ <a href="{@docRoot}training/tv/start/navigation.html">Creating TV Navigation</a>.
+</p>
+
+
+<h3 id="controller-disconnects">Handle controller disconnects</h3>
+
+<p>
+ Controllers for TV are frequently Bluetooth devices which may attempt to save power by periodically
+ going into sleep mode and disconnecting from the TV device. This means that an app might be
+ interrupted or restarted if it is not configured to handle these reconnect events. These events
+ can happen in any of the following circumstances:
+</p>
+
+<ul>
+ <li>While watching a video which is several minutes long, a D-Pad or game controller goes into
+ sleep mode, disconnects from the TV device and then reconnects later on.
+ </li>
+ <li>During gameplay, a new player joins the game using a game controller that is not currently
+ connected.
+ </li>
+ <li>During gameplay, a player leaves the game and disconnects a game controller.
+ </li>
+</ul>
+
+<p>
+ Any TV app activity that is subject to disconnect and reconnect events must be configured to
+ handle reconnection events in the app manifest. The following code sample demonstrates how to
+ enable an activity to handle configuration changes, including a keyboard or navigation device
+ connecting, disconnecting, or reconnecting:
+</p>
+
+<pre>
+&lt;activity
+ android:name=&quot;com.example.android.TvActivity&quot;
+ android:label=&quot;&#64;string/app_name&quot;
+ <strong>android:configChanges="keyboard|keyboardHidden|navigation"</strong>
+ android:theme=&quot;&#64;style/Theme.Leanback&quot;&gt;
+
+ &lt;intent-filter&gt;
+ &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
+ &lt;category android:name="android.intent.category.LEANBACK_LAUNCHER" /&gt;
+ &lt;/intent-filter&gt;
+ ...
+&lt;/activity&gt;
+</pre>
+
+<p>
+ This configuration change allows the app to continue running through a reconnection event, rather
+ than being restarted by the Android framework, which is not a good user experience.
+</p>
+
+
+<h3 id="d-pad-variants">Handle D-pad input variations</h3>
+
+<p>
+ TV device users may have more than one type of controller that they use with their TV. For
+ example, a user might have both a basic D-pad controller and a game controller. The key codes
+ provided by a game controller when it is being used for D-pad functions may vary from the key
+ codes sent by a physical D-pad.
+</p>
+
+<p>
+ Your app should handle the variations of D-pad input from a game controller, so the user does not
+ have to physically switch controllers to operate your app. For more information on handling these
+ input variations, see <a href="{@docRoot}training/game-controllers/controller-input.html#dpad">
+ Handling Controller Actions</a>.
+</p>
diff --git a/docs/html/training/tv/start/index.jd b/docs/html/training/tv/start/index.jd
new file mode 100644
index 0000000..ceefea1
--- /dev/null
+++ b/docs/html/training/tv/start/index.jd
@@ -0,0 +1,63 @@
+page.title=Building TV Apps
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+ <ul>
+ <li>Android 5.0 (API level 21) or higher</li>
+ <li>Android Studio 0.8 or later and Gradle 0.12 or later</li>
+ </ul>
+</div>
+</div>
+
+<p>
+ Android offers a rich user experience that's optimized for apps running on large screen devices,
+ such as high-definition televisions. Apps on TV offer new opportunities to delight your users
+ from the comfort of their couch.
+</p>
+
+<p>
+ TV apps use the same structure as those for phones and tablets. This approach means you can
+ create new TV apps based on what you already know about building apps for Android, or extend your
+ existing apps to also run on TV devices. However, the user interaction model for TV is
+ substantially different from phone and tablet devices. In order to make your app successful on TV
+ devices, you must design new layouts that can be easily understood from 10 feet away, and provide
+ navigation that works with just a directional pad and a select button.
+</p>
+
+<p>
+ This class describes how to start building apps for TV, including setting up your development
+ environment, basic requirements for layouts and navigation, as well as guidance on how to handle
+ hardware features that are not typically available on TV devices.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> You are encouraged to use <a href=
+ "{@docRoot}sdk/installing/studio.html">Android Studio</a> for building TV apps, because it
+ provides project setup, library inclusion, and packaging conveniences. This training assumes you
+ are using Android Studio.
+</p>
+
+
+<h2>Lessons</h2>
+
+<dl>
+ <dt><a href="{@docRoot}training/tv/start/start.html">
+ Getting Started with TV Apps</a></dt>
+ <dd>Learn how to create a new Android Studio project for TV apps or modify your existing
+ app project to run on TV devices.</dd>
+ <dt><a href="{@docRoot}training/tv/start/layouts.html">
+ Building TV Layouts</a></dt>
+ <dd>Learn the minimum requirements for TV layouts and how to implement them.</dd>
+ <dt><a href="{@docRoot}training/tv/start/navigation.html">
+ Creating TV Navigation</a></dt>
+ <dd>Learn the requirements for TV navigation and how to implement TV-compatible
+ navigation.</dd>
+ <dt><a href="{@docRoot}training/tv/start/hardware.html">
+ Handling TV Hardware</a></dt>
+ <dd>Learn how to check if your app is running on TV hardware, handle unsupported hardware
+ features, and manage controller devices.</dd>
+</dl>
diff --git a/docs/html/training/tv/start/layouts.jd b/docs/html/training/tv/start/layouts.jd
new file mode 100644
index 0000000..d2abe1d
--- /dev/null
+++ b/docs/html/training/tv/start/layouts.jd
@@ -0,0 +1,257 @@
+page.title=Building Layouts for TV
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you how to</h2>
+ <ol>
+ <li><a href="#themes">Use Layout Themes for TV</a></li>
+ <li><a href="#structure">Build Basic TV Layouts</a></li>
+ <li><a href="#visibility">Build Useable Text and Controls</a></li>
+ <li><a href="#density-resources">Manage Layout Resources for TV</a></li>
+ <li><a href="#anti-patterns">Avoid Layout Anti-Patterns</a></li>
+ <li><a href="#large-bitmaps">Handle Large Bitmaps</a></li>
+ </ol>
+ <h2>You should also read</h2>
+ <ol>
+ <li><a href="{@docRoot}design/tv/index.html">Android TV Design</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 you to create app layouts with TV
+ devices in mind in order to create a useful and enjoyable user experience.
+</p>
+
+<p>
+ This lesson describes the minimum requirements and implementation details for building effective
+ layouts in TV apps.
+</p>
+
+<h2 id="themes">Use Layout Themes for TV</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>
+ A support library for TV user interfaces called the <a href=
+ "{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback library</a> provides a
+ standard theme for TV activities, called {@code Theme.Leanback}. This theme establishes a
+ consistent visual style for TV apps. Use of this theme is recommended for most TV apps. This
+ theme is strongly recommended for any TV app that uses v17 leanback classes. The following code
+ sample shows how to apply this theme to a given activity within an app:
+</p>
+
+<pre>
+&lt;activity
+ android:name="com.example.android.TvActivity"
+ android:label="&#64;string/app_name"
+ <strong>android:theme="&#64;style/Theme.Leanback"</strong>&gt;
+</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 v17 leanback classes, you should apply this
+ theme to your TV activities to suppress the display of a title bar. 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>
+&lt;application&gt;
+ ...
+
+ &lt;activity
+ android:name="com.example.android.TvActivity"
+ android:label="&#64;string/app_name"
+ <strong>android:theme="&#64;android:style/Theme.NoTitleBar"</strong>&gt;
+ ...
+
+ &lt;/activity&gt;
+&lt;/application&gt;
+</pre>
+
+
+<h2 id="structure">Build Basic TV Layouts</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 mode.</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 <em>overscan</em>.
+</p>
+
+<p>
+ Avoid screen elements being clipped due to overscan and by incorporating 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>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;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" &gt;
+&lt;/LinearLayout&gt;
+</pre>
+
+<p class="caution">
+ <strong>Caution:</strong> Do not apply overscan margins to your layout if you are using the
+ v17 leanback classes, such as {@link android.support.v17.leanback.app.BrowseFragment} or related
+ widgets, as those layouts already incorporate overscan-safe margins.
+</p>
+
+<h2 id="visibility">Build Useable Text and Controls</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 your user interface elements 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>
+&lt;TextView
+ android:id="@+id/atext"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:singleLine="true"
+ <strong>android:textAppearance="?android:attr/textAppearanceMedium"/&gt;</strong>
+</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 (dip) units instead of absolute pixel units. For example, to set the
+ width of a widget, use {@code wrap_content} instead of a pixel measurement, and to set the
+ margin for a widget, use dip values instead of px values.</li>
+</ul>
+
+<p>
+ For more information about density-independent pixels and building layouts to handle larger
+ screen sizes, see <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+ Screens</a>.
+</p>
+
+<h2 id="density-resources">Manage Layout Resources for TV</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, which is not a good experience for the user. Use high-quality images instead.
+</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">Avoid Layout Anti-Patterns</h2>
+
+<p>
+ There are a few approaches to building layouts that you should avoid because they do not work
+ well on TV devices 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">Handle 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 are 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 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 main
+ user interface 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.
+ </li>
+</ul>
+
+<p>
+ For more information on getting the best performance when working with images, see
+ <a href="{@docRoot}training/displaying-bitmaps/index.html">Displaying Bitmaps Efficiently</a>.
+</p>
diff --git a/docs/html/training/tv/start/navigation.jd b/docs/html/training/tv/start/navigation.jd
new file mode 100644
index 0000000..1c9faca
--- /dev/null
+++ b/docs/html/training/tv/start/navigation.jd
@@ -0,0 +1,180 @@
+page.title=Creating TV Navigation
+page.tags="focus","selection","d-pad"
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you how to</h2>
+ <ol>
+ <li><a href="#d-pad-navigation">Enable D-pad Navigation</a></li>
+ <li><a href="#focus-selection">Provide Clear Focus and Selection</a></li>
+ </ol>
+
+</div>
+</div>
+
+<p>
+ TV devices provide a limited set of navigation controls for apps. Creating an effective
+ navigation scheme for your TV app depends on understanding these limited controls and the limits
+ of users' perception while operating your app. As you build your Android app for TVs,
+ pay special attention to how the user actually navigates around your app when using remote
+ control buttons instead of a touch screen.
+</p>
+
+<p>
+ This lesson explains the minimum requirements for creating effective TV app navigation scheme and
+ how to apply those requirements to your app.
+</p>
+
+
+<h2 id="d-pad-navigation">Enable D-pad Navigation</h2>
+
+<p>
+ On a TV device, users navigate with controls on a remote control device, using either a
+ directional pad (D-pad) or arrow keys. This type of control limits movement to up, down, left,
+ and right. To build a great TV-optimized app, you must provide a navigation scheme where the user
+ can quickly learn how to navigate your app using these limited controls.
+</p>
+
+<p>
+ The Android framework handles directional navigation between layout elements automatically, so
+ you typically do not need to do anything extra for your app. However, you should thoroughly test
+ navigation with a D-pad controller to discover any navigation problems. Follow these guidelines to
+ test that your app's navigation system works well with a D-pad on a TV device:
+</p>
+
+<ul>
+ <li>Ensure that a user with a D-pad controller can navigate to all visible controls on the
+ screen.
+ </li>
+ <li>For scrolling lists with focus, make sure that the D-pad up and down keys scroll the list,
+ and the Enter key selects an item in the list. Verify that users can select an element in the
+ list and that the list still scrolls when an element is selected.
+ </li>
+ <li>Ensure that switching between controls between controls is straightforward and predictable.
+ </li>
+</ul>
+
+
+<h3 id="modify-d-pad-nav">Modifying directional navigation</h3>
+
+<p>
+ The Android framework automatically applies a directional navigation scheme based on the
+ relative position of focusable elements in your layouts. You should test the generated
+ navigation scheme in your app using a D-pad controller. After testing, if you decide you want
+ users to move through your layouts in a specific way, you can set up explicit directional
+ navigation for your controls.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> You should only use these attributes to modify the navigation order if the
+ default order that the system applies does not work well.
+</p>
+
+<p>
+ The following code sample shows how to define the next control to receive focus for a {@link
+ android.widget.TextView} layout object:
+</p>
+
+<pre>
+&lt;TextView android:id="&#64;+id/Category1"
+ android:nextFocusDown="&#64;+id/Category2"\&gt;
+</pre>
+
+<p>
+ The following table lists all of the available navigation attributes for Android user interface
+ widgets:
+</p>
+
+<table>
+ <tr>
+ <th>Attribute</th>
+ <th>Function</th>
+ </tr>
+ <tr>
+ <td>{@link android.R.attr#nextFocusDown}</td>
+ <td>Defines the next view to receive focus when the user navigates down.</td>
+ </tr>
+ <tr>
+ <td>{@link android.R.attr#nextFocusLeft}</td>
+ <td>Defines the next view to receive focus when the user navigates left.</td>
+ </tr>
+ <tr>
+ <td>{@link android.R.attr#nextFocusRight}</td>
+ <td>Defines the next view to receive focus when the user navigates right.</td>
+ </tr>
+ <tr>
+ <td>{@link android.R.attr#nextFocusUp}</td>
+ <td>Defines the next view to receive focus when the user navigates up.</td>
+ </tr>
+</table>
+
+<p>
+ To use one of these explicit navigation attributes, set the value to the ID ({@code android:id}
+ value) of another widget in the layout. You should set up the navigation order as a loop, so that
+ the last control directs focus back to the first one.
+</p>
+
+
+
+<h2 id="focus-selection">Provide Clear Focus and Selection</h2>
+
+<p>
+ The success of an app's navigation scheme on TV devices is depends on how easy it is for
+ a user to determine what user interface element is in focus on screen. If you do not provide
+ clear indications of focused items (and therefore what item a user can take action on), they can
+ quickly become frustrated and exit your app. For the same reason, it is important to always have
+ an item in focus that a user can take action on immediately after your app starts, or any time
+ it is idle.
+</p>
+
+<p>
+ Your app layout and implementation should use color, size, animation, or a combination of these
+ attributes to help users easily determine what actions they can take next. Use a uniform scheme
+ for indicating focus across your application.
+</p>
+
+<p>
+ Android provides <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">
+ Drawable State List Resources</a> to implement highlights for focused and selected controls. The
+ following code example demonstrates how to enable visual behavior for a button to indicate that a
+ user has navigated to the control and then selected it:
+</p>
+
+<pre>
+&lt;!-- res/drawable/button.xml --&gt;
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:state_pressed="true"
+ android:drawable="@drawable/button_pressed" /&gt; &lt;!-- pressed --&gt;
+ &lt;item android:state_focused="true"
+ android:drawable="@drawable/button_focused" /&gt; &lt;!-- focused --&gt;
+ &lt;item android:state_hovered="true"
+ android:drawable="@drawable/button_focused" /&gt; &lt;!-- hovered --&gt;
+ &lt;item android:drawable="@drawable/button_normal" /&gt; &lt;!-- default --&gt;
+&lt;/selector&gt;
+</pre>
+
+<p>
+ The following layout XML sample code applies the previous state list drawable to a
+ {@link android.widget.Button}:
+</p>
+
+<pre>
+&lt;Button
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:background="@drawable/button" /&gt;
+</pre>
+
+<p>
+ Make sure to provide sufficient padding within the focusable and selectable controls so that the
+ highlights around them are clearly visible.
+</p>
+
+<p>
+ For more recommendations on designing effective selection and focus for your TV app, see
+ <a href="{@docRoot}design/tv/patterns.html">Patterns for TV</a>.
+</p>
diff --git a/docs/html/training/tv/start/start.jd b/docs/html/training/tv/start/start.jd
new file mode 100644
index 0000000..bebeedd
--- /dev/null
+++ b/docs/html/training/tv/start/start.jd
@@ -0,0 +1,259 @@
+page.title=Get Started with TV Apps
+page.tags="leanback","recyclerview","launcher"
+
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>This lesson teaches you how to</h2>
+ <ol>
+ <li><a href="#dev-project">Setup a TV Project</a></li>
+ <li><a href="#build-it">Build TV Apps</a></li>
+ <li><a href="#run">Run TV Apps</a></li>
+ </ol>
+ <h2>You should also read</h2>
+ <ol>
+ <li><a href="{@docRoot}design/tv/index.html">
+ TV Design</a></li>
+ <li><a href="{@docRoot}training/tv/start/layouts.html">
+ Building TV Layouts</a></li>
+ </ol>
+</div>
+</div>
+
+<p>
+ TV apps use the same structure as those for phones and tablets. This similarity means you can
+ modify your existing apps to also run on TV devices or create new apps based on what you already
+ know about building apps for Android.
+</p>
+
+<p class="note">
+ <strong>Important:</strong> There are specific requirements your app must meet to
+ qualify as an Android TV app on Google Play. For more information, see the requirements listed
+ in <a href="{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a>.
+</p>
+
+<p>
+ This lesson describes how to prepare your development environment for building TV apps, and the
+ minimum required changes to enable an app to run on TV devices.
+</p>
+
+
+<h2 id="dev-project">Set up a TV Project</h2>
+
+<p>
+ This section discusses how to modify an existing app to run on TV devices, or create a new one.
+ These are the main components you must use to create an app that runs on TV devices:
+</p>
+
+<ul>
+ <li><strong>Activity for TV</strong> (Required) - In your application manifest,
+ declare an activity that is intended to run on TV devices.</li>
+ <li><strong>TV Support Libraries</strong> (Optional) - There are several
+ <a href="#tv-libraries">Support Libraries</a>
+ available for TV devices that provide widgets for building user interfaces.</li>
+</ul>
+
+
+<h3 id="prerequisites">Prerequisites</h3>
+
+<p>Before you begin building apps for TV, you must:</p>
+
+<ul>
+ <li><strong><a href="{@docRoot}sdk/installing/adding-packages.html#GetTools">
+ Update your SDK tools to version 24.0.0 or higher</a></strong>
+ <br>
+ The updated SDK tools enable you to build and test apps for TV.
+ </li>
+ <li><strong><a href="{@docRoot}sdk/installing/adding-packages.html#GetTools">
+ Update your SDK with Android 5.0 (API 21) or higher</a></strong>
+ <br>
+ The updated platform version provides new APIs for TV apps.
+ </li>
+ <li><strong><a href="{@docRoot}sdk/installing/create-project.html">
+ Create or update your app project</a></strong>
+ <br>
+ In order to access new APIs for TV devices, you must create a project or modify an existing
+ project that targets Android 5.0 (API level 21) or higher.
+ </li>
+</ul>
+
+
+<h3 id="tv-activity">Declare a TV Activity</h3>
+
+<p>An application intended to run on TV devices must declare a launcher activity for TV
+ in its manifest using a {@link android.content.Intent#CATEGORY_LEANBACK_LAUNCHER} intent filter.
+ This filter identifies your app as being enabled for TV, allowing it to be considered a TV app
+ in Google Play. Declaring this intent also identifies which activity
+ in your app to launch when a user selects its icon on the TV home screen.</p>
+
+<p class="caution">
+ <strong>Caution:</strong> If you do not include the {@link android.content.Intent#CATEGORY_LEANBACK_LAUNCHER} intent filter in
+ your app, it is not visible to users running the Google Play store on TV devices. Also, if your
+ app does not have this filter when you load it onto a TV device using developer tools, the app
+ does not appear in the TV user interface.
+</p>
+
+<p>The following code snippet shows how to include this intent filter in your manifest:</p>
+
+<pre>
+&lt;application&gt;
+ ...
+ &lt;activity
+ android:name=&quot;com.example.android.MainActivity&quot;
+ android:label=&quot;@string/app_name&quot; &gt;
+
+ &lt;intent-filter&gt;
+ &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
+ &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
+ &lt;/intent-filter&gt;
+ &lt;/activity&gt;
+
+ &lt;activity
+ android:name=&quot;com.example.android.<strong>TvActivity</strong>&quot;
+ android:label=&quot;&#64;string/app_name&quot;
+ android:theme=&quot;&#64;style/Theme.Leanback&quot;&gt;
+
+ &lt;intent-filter&gt;
+ &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
+ &lt;category android:name="<strong>android.intent.category.LEANBACK_LAUNCHER</strong>" /&gt;
+ &lt;/intent-filter&gt;
+
+ &lt;/activity&gt;
+&lt;/application&gt;
+</pre>
+
+<p>
+ The second activity manifest entry in this example specifies that activity as the one to
+ launch on a TV device.
+</p>
+
+<p>
+ If you are modifying an existing app for use on TV, your app should not use the same
+ activity layout for TV that it does for phones and tablets. The user interface of your TV app (or
+ TV portion of your existing app) should provide a simpler interface that can be easily navigated
+ using a remote control from a couch. For guidelines on designing an app for TV, see the <a href=
+ "{@docRoot}design/tv/index.html">TV Design</a> guide. For more information on the minimum
+ implementation requirements for interface layouts on TV, see <a href=
+ "{@docRoot}training/tv/start/layouts.html">Building TV Layouts</a>.
+</p>
+
+
+<h3 id="tv-libraries">Add TV support libraries</h3>
+
+<p>
+ The Android SDK includes support libraries that are intended for use with TV apps. These
+ libraries provide APIs and user interface widgets for use on TV devices. The libraries are
+ located in the {@code &lt;sdk&gt;/extras/android/support/} directory. Here is a list of the
+ libraries and their general purpose:
+</p>
+
+<ul>
+ <li><a href="{@docRoot}tools/support-library/features.html#v17-leanback">
+ <strong>v17 leanback library</strong></a> - Provides user interface widgets for TV apps,
+ particularly for apps that do media playback.
+ </li>
+ <li><a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">
+ <strong>v7 recyclerview library</strong></a> - Provides classes for managing display of long
+ lists in a memory efficient manner. Several classes in the v17 leanback library depend on the
+ classes in this library.
+ </li>
+ <li><a href="{@docRoot}tools/support-library/features.html#v7-cardview">
+ <strong>v7 cardview library</strong></a> - Provides user interface widgets for displaying
+ information cards, such as media item pictures and descriptions.
+ </li>
+</ul>
+
+<p class="note">
+ <strong>Note:</strong> You are not required to use these support libraries for your TV app.
+ However, we strongly recommend using them, particularly for apps that provide a media catalog
+ browsing interface.
+</p>
+
+<p>
+ If you decide to use the v17 leanback library for your app, you should note that it is dependent
+ on the <a href="{@docRoot}tools/support-library/features.html#v4">v4 support library</a>. This
+ means that apps that use the leanback support library should include all of these support
+ libraries:
+</p>
+
+<ul>
+ <li>v4 support library</li>
+ <li>v7 recyclerview support library</li>
+ <li>v17 leanback support library</li>
+</ul>
+
+<p>
+ The v17 leanback library contains resources, which require you to take specific steps to include
+ it in app projects. For instructions on importing a support library with resources, see
+ <a href="{@docRoot}tools/support-library/setup.html#libs-with-res">Support Library Setup</a>.
+</p>
+
+
+<h2 id="build-it">Build TV Apps</h2>
+
+<p>After you have completed the steps described above, it's time to start building apps for
+ the big screen! Check out these additional topics to help you build your app for TV:
+
+<ul>
+ <li>
+ <a href="{@docRoot}training/tv/playback/index.html">Building TV Playback Apps</a> - TVs are
+ built to entertain, so Android provides a set of user interface tools and widgets for building
+ TV apps that play videos and music, and let users browse for the content they want.
+ </li>
+ <li>
+ <a href="{@docRoot}training/tv/search/index.html">Surfacing Content on TV</a> - With all the
+ content choices at users' fingertips, helping them find content they enjoy is almost as important
+ as providing that content. This training discusses how to surface your content on TV devices.
+ </li>
+ <li>
+ <a href="{@docRoot}training/tv/games/index.html">Games for TV</a> - TV devices are a great
+ platform for games. See this topic for information on building great game experiences for TV.
+ </li>
+</ul>
+
+
+<h2 id="run">Run TV Apps</h2>
+
+<p>
+ Running your app is an important part of the development process. The AVD Manager in the Android
+ SDK provides the device definitions that allow you to create virtual TV devices for running and
+ testing your applications.
+</p>
+
+<p>To create an virtual TV device:</p>
+
+<ol>
+ <li>Start the AVD Manager. For more information, see the
+ <a href="{@docRoot}tools/help/avd-manager.html">AVD Manager</a> help.</li>
+ <li>In the AVD Manager dialog, click the <strong>Device Definitions</strong> tab.</li>
+ <li>Select one of the Android TV device definitions and click <strong>Create AVD</strong>.</li>
+ <li>Select the emulator options and click <strong>OK</strong> to create the AVD.
+ <p class="note">
+ <strong>Note:</strong> For best performance of the TV emulator device, enable the <strong>Use
+ Host GPU</strong> option and, where supported, use virtual device acceleration. For
+ more information on hardware acceleration of the emulator, see
+ <a href="{@docRoot}tools/devices/emulator.html#acceleration">Using the Emulator</a>.
+ </p>
+ </li>
+</ol>
+
+<p>To test your application on the virtual TV device:</p>
+
+<ol>
+ <li>Compile your TV application in your development environment.</li>
+ <li>Run the application from your development environment and choose the TV virtual device as
+ the target.</li>
+</ol>
+
+<p>
+ For more information about using emulators see, <a href="{@docRoot}tools/devices/emulator.html">
+ Using the Emulator</a>. For more information on deploying apps from Android Studio to virtual
+ devices, see <a href="{@docRoot}sdk/installing/studio-debug.html">Debugging with Android
+ Studio</a>. For more information about deploying apps to emulators from Eclipse with ADT, see
+ <a href="{@docRoot}tools/building/building-eclipse.html">Building and Running from Eclipse with
+ ADT</a>.
+</p>
diff --git a/docs/html/training/tv/tif/index.jd b/docs/html/training/tv/tif/index.jd
new file mode 100644
index 0000000..4746e42
--- /dev/null
+++ b/docs/html/training/tv/tif/index.jd
@@ -0,0 +1,48 @@
+page.title=Building Live TV Apps
+page.tags=tif
+page.article=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}reference/android/media/tv/package-summary.html">
+ android.media.tv</a></li>
+ </ul>
+</div>
+</div>
+
+<p>
+ Watching live television shows and other continuous, channel-based content is a big part of the
+ TV experience. Android supports receiving and playback of live video content through the TV Input
+ Framework in Android 5.0 (API level 21).
+ This framework provides a unified method for receiving audio and video channel content
+ from hardware sources, such as HDMI ports and built-in-tuners, and software sources, such as
+ video streamed over the internet.
+</p>
+<p>
+ The framework enables developers to define live TV input sources by implementing a TV input
+ service. This service publishes a list of channels and programs to the TV Provider. The live TV
+ app on a TV device gets the list of available channels and programs from the TV Provider and
+ displays them to a user. When a user selects a specific channel, the live TV app creates a
+ session for the associated TV input service through the TV Input Manager, and tells the TV input
+ service to tune to the requested channel and play the content to a display surface provided by
+ the TV app.
+</p>
+
+<img src="{@docRoot}images/tv/tv-tif-overview.png" id="figure1">
+<p class="img-caption">
+ <strong>Figure 1.</strong> Functional diagram of the TV Input Framework
+</p>
+
+<p>
+ The TV Input Framework is designed to provide access to a wide variety of live TV input sources
+ and bring them together in a single user interface for users to browse, view, and enjoy content.
+ Building a TV input service for your content can help make it more accessible on TV devices.
+</p>
+
+<p>For more information about TV Input Framework, see the
+<a href="{@docRoot}reference/android/media/tv/package-summary.html">android.media.tv</a>
+reference.</p>
diff --git a/docs/html/training/tv/unsupported-features-tv.jd b/docs/html/training/tv/unsupported-features-tv.jd
deleted file mode 100644
index a9f090b..0000000
--- a/docs/html/training/tv/unsupported-features-tv.jd
+++ /dev/null
@@ -1,157 +0,0 @@
-page.title=Handling Features Not Supported on TV
-parent.title=Designing for TV
-parent.link=index.html
-
-trainingnavtop=true
-previous.title=Optimizing Navigation for TV
-previous.link=optimizing-navigation-tv.html
-
-@jd:body
-
-<div id="tb-wrapper">
-<div id="tb">
-
-<h2>This lesson teaches you to</h2>
-<ol>
- <li><a href="#WorkaroundUnsupportedFeatures">Work Around Features Not Supported on TV</a></li>
- <li><a href="#CheckAvailableFeatures">Check for Available Features at Runtime</a></li>
-</ol>
-
-</div>
-</div>
-
-<p>
-TVs are much different from other Android-powered devices:
-</p>
-<ul>
- <li>They're not mobile.</li>
- <li>Out of habit, people use them for watching media with little or no interaction.</li>
- <li>People interact with them from a distance.</li>
-</ul>
-
-<p>
-Because TVs have a different purpose from other devices, they usually don't have hardware features
-that other Android-powered devices often have. For this reason, the Android system does not
-support the following features for a TV device:
-<table>
-<tr>
-<th>Hardware</th>
-<th>Android feature descriptor</th>
-</tr>
-<tr>
-<td>Camera</td>
-<td>android.hardware.camera</td>
-</tr>
-<tr>
-<td>GPS</td>
-<td>android.hardware.location.gps</td>
-</tr>
-<tr>
-<td>Microphone</td>
-<td>android.hardware.microphone</td>
-</tr>
-<tr>
-<td>Near Field Communications (NFC)</td>
-<td>android.hardware.nfc</td>
-</tr>
-<tr>
-<td>Telephony</td>
-<td>android.hardware.telephony</td>
-</tr>
-<tr>
-<td>Touchscreen</td>
-<td>android.hardware.touchscreen</td>
-</tr>
-</table>
-</p>
-
-<p>
-This lesson shows you how to work around features that are not available on TV by:
-<ul>
- <li>Providing work arounds for some non-supported features.</li>
- <li>Checking for available features at runtime and conditionally activating/deactivating certain code
- paths based on availability of those features.</li>
-</ul>
-</p>
-
-
-<h2 id="WorkaroundUnsupportedFeatures">Work Around Features Not Supported on TV</h2>
-
-<p>
-Android doesn't support touchscreen interaction for TV devices, most TVs don't have touch screens,
-and interacting with a TV using a touchscreen is not consistent with the 10 foot environment. For
-these reasons, users interact with Android-powered TVs using a remote. In consideration of this,
-ensure that every control in your app can be accessed with the D-pad. Refer back to the previous two lessons
-<a href="{@docRoot}training/tv/optimizing-layouts-tv.html">Optimizing Layouts for TV</a> and
-<a href="{@docRoot}training/tv/optimizing-navigation-tv.html">Optimize Navigation for TV</a> for
-more details
-on this topic. The Android system assumes that a device has a touchscreen, so if you want your application
-to run on a TV, you must <strong>explicitly</strong> disable the touchscreen requirement in your manifest file:
-<pre>
-&lt;uses-feature android:name="android.hardware.touchscreen" android:required="false"/&gt;
-</pre>
-</p>
-
-<p>
-Although a TV doesn't have a camera, you can still provide a photography-related application on a TV.
-For example, if you have an app that takes, views and edits photos, you can disable its picture-taking
-functionality for TVs and still allow users to view and even edit photos. The next section talks about how to
-deactivate or activate specific functions in the application based on runtime device type detection.
-</p>
-
-<p>
-Because TVs are stationary, indoor devices, they don't have built-in GPS. If your application uses location
-information, allow users to search for a location or use a "static" location provider to get
-a location from the zip code configured during the TV setup.
-<pre>
-LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
-Location location = locationManager.getLastKnownLocation("static");
-Geocoder geocoder = new Geocoder(this);
-Address address = null;
-
-try {
- address = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1).get(0);
- Log.d("Zip code", address.getPostalCode());
-
-} catch (IOException e) {
- Log.e(TAG, "Geocoder error", e);
-}
-</pre>
-</p>
-
-<p>
-TVs usually don't support microphones, but if you have an application that uses voice control,
-you can create a mobile device app that takes voice input and then acts as a remote control for a TV.
-</p>
-
-<h2 id="CheckAvailableFeatures">Check for Available Features at Runtime</h2>
-
-<p>
-To check if a feature is available at runtime, call
-{@link android.content.pm.PackageManager#hasSystemFeature(String)}.
- This method takes a single argument : a string corresponding to the
-feature you want to check. For example, to check for touchscreen, use
-{@link android.content.pm.PackageManager#hasSystemFeature(String)} with the argument
-{@link android.content.pm.PackageManager#FEATURE_TOUCHSCREEN}.
-</p>
-
-<p>
-The following code snippet demonstrates how to detect device type at runtime based on supported features:
-
-<pre>
-// Check if android.hardware.telephony feature is available.
-if (getPackageManager().hasSystemFeature("android.hardware.telephony")) {
- Log.d("Mobile Test", "Running on phone");
-// Check if android.hardware.touchscreen feature is available.
-} else if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) {
- Log.d("Tablet Test", "Running on devices that don't support telphony but have a touchscreen.");
-} else {
- Log.d("TV Test", "Running on a TV!");
-}
-</pre>
-</p>
-
-<p>
-This is just one example of using runtime checks to deactivate app functionality that depends on features
-that aren't available on TVs.
-</p> \ No newline at end of file
diff --git a/docs/html/training/wearables/apps/layouts.jd b/docs/html/training/wearables/apps/layouts.jd
index e9eacd3..e62d3e5 100644
--- a/docs/html/training/wearables/apps/layouts.jd
+++ b/docs/html/training/wearables/apps/layouts.jd
@@ -82,7 +82,7 @@ PendingIntent notificationPendingIntent = PendingIntent.getActivity(this, 0, not
users view your notification.
</li>
<li>Issue the notification using the
- {@link android.app.NotificationManager#notify notify()} method.
+ <a href="{@docRoot}reference/android/app/NotificationManager.html#notify(int, android.app.Notification)"><code>notify()</code></a> method.
<p class="note"><b>Note:</b> When the notification is peeking on the homescreen, the system
displays it with a standard template that it generates from the notification's semantic data. This template works well on all watchfaces. When users swipe the notification up, they'll then see the
custom activity for the notification.</p>
diff --git a/docs/html/training/wearables/notifications/creating.jd b/docs/html/training/wearables/notifications/creating.jd
index 9398f96..84e3311 100644
--- a/docs/html/training/wearables/notifications/creating.jd
+++ b/docs/html/training/wearables/notifications/creating.jd
@@ -155,7 +155,7 @@ PendingIntent actionPendingIntent =
// Create the action
NotificationCompat.Action action =
new NotificationCompat.Action.Builder(R.drawable.ic_action,
- getString(R.string.label, actionPendingIntent))
+ getString(R.string.label), actionPendingIntent)
.build();
// Build the notification and add the action via WearableExtender