docs: Add docs on OnboardingFragment

Add a dev guide for OnboardingFragment, used to show
information to a first-time user in an Android TV app.

Bug: 26488857
Change-Id: I91305bf4013090e84c8771206f1144d210c038db
diff --git a/docs/html/images/training/tv/playback/onboarding-fragment-diagram.png b/docs/html/images/training/tv/playback/onboarding-fragment-diagram.png
new file mode 100644
index 0000000..5839a50
--- /dev/null
+++ b/docs/html/images/training/tv/playback/onboarding-fragment-diagram.png
Binary files differ
diff --git a/docs/html/images/training/tv/playback/onboarding-fragment.png b/docs/html/images/training/tv/playback/onboarding-fragment.png
new file mode 100644
index 0000000..5b7da55
--- /dev/null
+++ b/docs/html/images/training/tv/playback/onboarding-fragment.png
Binary files differ
diff --git a/docs/html/images/training/tv/playback/onboarding-fragment_2x.png b/docs/html/images/training/tv/playback/onboarding-fragment_2x.png
new file mode 100644
index 0000000..0034be4
--- /dev/null
+++ b/docs/html/images/training/tv/playback/onboarding-fragment_2x.png
Binary files differ
diff --git a/docs/html/training/_book.yaml b/docs/html/training/_book.yaml
index 0523ec9e..6e97a8e 100644
--- a/docs/html/training/_book.yaml
+++ b/docs/html/training/_book.yaml
@@ -695,6 +695,8 @@
         value: 再生中カードを表示する
     - title: Adding a Guided Step
       path: /training/tv/playback/guided-step.html
+    - title: Introducing First-time Users to Your App
+      path: /training/tv/playback/onboarding.html
     - title: Enabling Background Playback
       path: /training/tv/playback/options.html
     - title: Adding Picture-in-picture
diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd
index d5e4e67..34c6287 100644
--- a/docs/html/training/tv/playback/index.jd
+++ b/docs/html/training/tv/playback/index.jd
@@ -69,6 +69,10 @@
     <dd>Learn how to use the Leanback support library to guide a user through a series of
+  <dt><b><a href="onboarding.html">Introducing First-time Users to Your App</a></b></dt>
+    <dd>Learn how to use the Leanback support library to show first-time users
+    how to get the most out of your app.</dd>
   <dt><b><a href="options.html">Enabling Background Playback</a></b></dt>
     <dd>Learn how to continue playback when the user clicks on <strong>Home</strong>.</dd>
diff --git a/docs/html/training/tv/playback/onboarding.jd b/docs/html/training/tv/playback/onboarding.jd
new file mode 100644
index 0000000..bb41bec
--- /dev/null
+++ b/docs/html/training/tv/playback/onboarding.jd
@@ -0,0 +1,377 @@
+page.title=Introducing First-time Users to Your App
+<div id="tb-wrapper">
+<div id="tb">
+  <h2>This lesson teaches you to</h2>
+  <ol>
+    <li><a href="#addFragment">Add an OnboardingFragment</a></li>
+    <li><a href="#pageContent">Add OnboardingFragment Pages</a></li>
+    <li><a href="#logoScreen">Add an Initial Logo Screen</a></li>
+    <li><a href="#pageAnimations">Customize Page Animations</a></li>
+    <li><a href="#themes">Customize Themes</a></li>
+  </ol>
+  <h2>Try it out</h2>
+  <ul>
+    <li><a class="external-link" href="">Android
+    Leanback sample app</a></li>
+  </ul>
+To show a first-time user how to get the most from your app, present
+onboarding information at app startup. Here are some examples of onboarding
+<li>Present detailed information on which channels are available when a user
+first accesses a channel app.</li>
+<li>Call attention to noteworthy features in your app.</li>
+<li>Illustrate any required or recommended steps that users should take when
+using the app for the first time.</li>
+<p>The <a href=
+"{@docRoot}tools/support-library/features.html#v17-leanback">v17 Leanback
+support library</a> provides the
+{@link} class for
+presenting first-time user information. This lesson describes how to use the
+{@link} class to present
+introductory information that is shown when the app launches for the first
+time. {@link} uses TV UI
+best practices to present the information in a way that matches TV UI styles,
+and is easy to navigate on TV devices.</p>
+<img src="{@docRoot}images/training/tv/playback/onboarding-fragment.png"
+srcset="{@docRoot}images/training/tv/playback/onboarding-fragment.png 1x,
+{@docRoot}images/training/tv/playback/onboarding-fragment_2x.png 2x" />
+<p class="img-caption"><strong>Figure 1.</strong> An example
+<p>Your {@link} should
+not contain UI elements that require user input, such as buttons and fields.
+Similarly, it should not be used as a UI element for a task the user will do
+regularly. If you need to present a multi-page UI that requires
+user input, consider using a
+<h2 id="addFragment">Add an OnboardingFragment</h2>
+<p>To add an {@link}
+to your app, implement a class that extends
+the {@link} class. Add
+this fragment to an activity, either via the activity's layout XML, or
+programmatically. Make sure the activity or
+fragment is using a theme derived from
+as described in <a href="#themes">Customize Themes</a>.</p>
+<p>In the {@link onCreate()} method of your
+app's main activity, call
+{@link startActivity()}
+with an {@link android.content.Intent} that points to your
+{@link OnboardingFragment's}
+parent activity. This ensures that your
+{@link} appears as
+soon as your app starts.<p>
+<p>To ensure that the
+{@link} only appears the
+first time that the user starts your app, use a
+{@link android.content.SharedPreferences} object
+to track whether the user has already viewed the
+{@link}. Define a boolean
+value that changes to true when the user finishes viewing the
+{@link}. Check
+this value in your main activity’s
+{@link onCreate()}, and only start the
+{@link} parent activity if
+the value is false. The following example shows an override of
+{@link onCreate()} that checks for a
+{@link android.content.SharedPreferences} value and, if not set to true, calls
+{@link startActivity()} to
+show the {@link}:</p>
+protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    setContentView(R.layout.activity_main);
+    SharedPreferences sharedPreferences =
+            PreferenceManager.getDefaultSharedPreferences(this);
+    // Check if we need to display our OnboardingFragment
+    if (!sharedPreferences.getBoolean(
+            MyOnboardingFragment.COMPLETED_ONBOARDING_PREF_NAME, false)) {
+        // The user hasn't seen the OnboardingFragment yet, so show it
+        startActivity(new Intent(this, OnboardingActivity.class));
+    }
+<p>After the user views the
+{@link}, mark it as viewed
+using the {@link android.content.SharedPreferences} object. To do this, in your
+{@link}, override
+onFinishFragment()} and set your {@link android.content.SharedPreferences} value
+to true, as shown in the following example:
+protected void onFinishFragment() {
+    super.onFinishFragment();
+    // User has seen OnboardingFragment, so mark our SharedPreferences
+    // flag as completed so that we don't show our OnboardingFragment
+    // the next time the user launches the app.
+    SharedPreferences.Editor sharedPreferencesEditor =
+            PreferenceManager.getDefaultSharedPreferences(getContext()).edit();
+    sharedPreferencesEditor.putBoolean(
+    sharedPreferencesEditor.apply();
+<h2 id="pageContent">Add OnboardingFragment Pages</h2>
+<p>After you add your
+{@link}, you need to define
+the onboarding pages. An
+{@link} displays content
+in a series of ordered pages. Each page can have a title, description, and
+several sub-views that can contain images or animations.</p>
+<img src="{@docRoot}images/training/tv/playback/onboarding-fragment-diagram.png"
+/><p class="img-caption"><strong>Figure 2.</strong> OnboardingFragment
+page elements.
+<p>Figure 2 shows an example page with callouts marking customizable page
+elements that your {@link}
+can provide. The page elements are:</p>
+<li>The page title.</li>
+<li>The page description.</li>
+<li>The page content view, in this case a simple green checkmark in a grey box.
+This view is optional. Use this view to illustrate page details such as a
+screenshot that highlights the app feature that the page describes.</li>
+<li>The page background view, in this case a simple blue gradient. This view
+always renders behind other views on the page. This view is optional.</li>
+<li>The page foreground view, in this case a logo. This view always renders
+in front of all other views on the page. This view is optional.</li>
+<p>Initialize page information when your
+{@link} is first created
+or attached to the parent activity, as the system requests page
+information when it creates the fragment's view. You can initialize page
+information in your class constructor or in an override of
+{@link onAttach()}.</p>
+<p>Override each of the following methods that provide page information
+to the system:</p>
+getPageCount()} returns the number of pages in your
+getPageTitle()} returns the title for the requested page number.</li>
+getPagedescription()} returns the description for the requested page
+<p>Override each of the following methods to provide optional sub-views used
+to display images or animations:</p>
+onCreateBackgroundView()} returns a {@link android.view.View} that you
+create to act as the background view, or null if no background view is needed.
+onCreateContentView()} returns a {@link android.view.View} that you
+create to act as the content view, or null if no content view is needed.
+onCreateForegroundView()} returns a {@link android.view.View} that you
+create to act as the foreground view, or null if no foreground view is needed.
+<p>The system adds the {@link android.view.View} that you create to the page
+layout. The following example overrides
+onCreateContentView()} and returns an {@link android.widget.ImageView}:</p>
+private ImageView mContentView;
+protected View onCreateContentView(LayoutInflater inflater, ViewGroup container) {
+    mContentView = new ImageView(getContext());
+    mContentView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+    mContentView.setImageResource(R.drawable.onboarding_content_view);
+    mContentView.setPadding(0, 32, 0, 32);
+    return mContentView;
+<h2 id="logoScreen">Add an Initial Logo Screen</h2>
+<p>Your {@link} can start
+with an optional logo screen that introduces your app. If you want to display
+a {@link} as your logo screen, in your
+{@link OnboardingFragment's}
+{@link onCreate()} method, call
+setLogoResourceId()} with the ID of your
+{@link}. The
+system will fade in and briefly display this
+{@link}, and then fade out the
+before displaying the first page of your
+<p>If you want to provide a custom animation for your logo screen, instead of
+setLogoResourceId()}, override
+onCreateLogoAnimation()} and return an {@link android.animation.Animator}
+object that renders your custom animation, as shown in the following example:
+public Animator onCreateLogoAnimation() {
+    return AnimatorInflater.loadAnimator(mContext,
+            R.animator.onboarding_logo_screen_animation);
+<h2 id="pageAnimations">Customize Page Animations</h2>
+<p>The system uses default animations when displaying the first page of your
+{@link} and when the user
+navigates to a different page. You can customize these animations by
+overriding methods in your
+<p>To customize the animation that appears on your first page,
+onCreateEnterAnimation()} and return an {@link android.animation.Animator}.
+The following example creates an
+{@link android.animation.Animator} that scales the content view
+protected Animator onCreateEnterAnimation() {
+    Animator startAnimator = ObjectAnimator.ofFloat(mContentView,
+            View.SCALE_X, 0.2f, 1.0f).setDuration(ANIMATION_DURATION);
+    return startAnimator;
+<p>To customize the animation used when the user navigates to a different page,
+onPageChanged()}. In your
+onPageChanged()} method, create {@link android.animation.Animator Animators}
+that remove the previous page and display the next page, add these to an
+{@link android.animation.AnimatorSet}, and play the set. The following
+example uses a fade-out animation to remove the previous page, updates the
+content view image, and uses a fade-in animation to display the next page:</p>
+protected void onPageChanged(final int newPage, int previousPage) {
+    // Create a fade-out animation used to fade out previousPage and, once
+    // done, swaps the contentView image with the next page's image.
+    Animator fadeOut = ObjectAnimator.ofFloat(mContentView,
+            View.ALPHA, 1.0f, 0.0f).setDuration(ANIMATION_DURATION);
+    fadeOut.addListener(new AnimatorListenerAdapter() {
+        &#64;Override
+        public void onAnimationEnd(Animator animation) {
+            mContentView.setImageResource(pageImages[newPage]);
+        }
+    });
+    // Create a fade-in animation used to fade in nextPage
+    Animator fadeIn = ObjectAnimator.ofFloat(mContentView,
+            View.ALPHA, 0.0f, 1.0f).setDuration(ANIMATION_DURATION);
+    // Create AnimatorSet with our fade-out and fade-in animators, and start it
+    AnimatorSet set = new AnimatorSet();
+    set.playSequentially(fadeOut, fadeIn);
+    set.start();
+<p>For more details about how to create
+{@link android.animation.Animator Animators} and
+{@link android.animation.AnimatorSet AnimatorSets}, see
+<a href="">
+Property Animations</a>.</p>
+<h2 id="themes">Customize Themes</h2>
+<p>Any {@link}
+implementation must use either the
+{@link} theme
+or a theme that inherits from
+{@link}. Set the
+theme for your {@link} by
+doing one of the following:</p>
+<li>Set the {@link
+OnboardingFragment's} parent activity to use the desired theme. The following
+example shows how to set an activity to use
+{@link} in the
+app manifest:
+   android:name=".OnboardingActivity"
+   android:enabled="true"
+   android:exported="true"
+   android:theme="&#64;style/Theme.Leanback.Onboarding"&gt;
+Set the theme in the parent activity by using the
+attribute in a custom activity theme. Point this attribute to another
+custom theme that only the
+objects in your activity use. Use this approach if your activity already uses
+a custom theme and you don't want to apply
+{@link} styles to other
+views in the activity.
+onProvideTheme()} and return the desired theme. Use this approach if
+multiple activities use your
+or if the parent activity can't use the desired theme.
+The following example overrides
+onProvideTheme()} and returns
+public int onProvideTheme() {
+   return;
\ No newline at end of file
diff --git a/docs/image_sources/training/tv/playback/ b/docs/image_sources/training/tv/playback/
new file mode 100644
index 0000000..89a799b
--- /dev/null
+++ b/docs/image_sources/training/tv/playback/
Binary files differ