1page.title=Adding a Guided Step
2page.tags=tv,guided step,GuidedStepFragment,GuidedAction
3page.keywords=tv,GuidedStepFragment,GuidedAction
4helpoutsWidget=true
5
6trainingnavtop=true
7
8@jd:body
9
10<div id="tb-wrapper">
11<div id="tb">
12  <h2>This lesson teaches you to</h2>
13  <ol>
14    <li><a href="#details">Provide Details for a Step</a></li>
15    <li><a href="#actions">Create and Handle User Actions</a></li>
16    <li><a href="#sequence">Group Guided Steps Into a Guided Sequence</a></li>
17    <li><a href="#presentation">Customize Step Presentation</a></li>
18  </ol>
19  <h2>Try it out</h2>
20  <ul>
21    <li><a class="external-link" href="https://github.com/googlesamples/androidtv-Leanback">Android
22    Leanback sample app</a></li>
23  </ul>
24</div>
25</div>
26
27<p>
28Your application might have multi-step tasks for users. For example, your app might need to guide
29users through purchasing additional content, or setting up a complex configuration setting, or
30simply confirming a decision. All of these tasks require walking users through one or more ordered
31steps or decisions.
32</p>
33
34<p>
35The <a href=
36"{@docRoot}tools/support-library/features.html#v17-leanback">v17 Leanback support library</a>
37provides classes to implement multi-step user tasks. This lesson discusses how to use the
38{@link android.support.v17.leanback.app.GuidedStepFragment} class to guide a user through a series
39of decisions to accomplish a task. {@link android.support.v17.leanback.app.GuidedStepFragment} uses
40TV UI best practices to make multi-step tasks easy to understand and navigate on TV devices.
41</p>
42
43<h2 id="details">Provide Details for a Step</h2>
44
45<p>
46A {@link android.support.v17.leanback.app.GuidedStepFragment} represents a single step in a series
47of steps. Visually it provides a guidance view on the left with step information. On the right,
48{@link android.support.v17.leanback.app.GuidedStepFragment} provides a view containing a
49list of possible actions or decisions for this step.
50</p>
51
52<img src="{@docRoot}images/training/tv/playback/guided-step-screen.png"
53srcset="{@docRoot}images/training/tv/playback/guided-step-screen.png 1x,
54{@docRoot}images/training/tv/playback/guided-step-screen-2x.png 2x" />
55<p class="img-caption"><strong>Figure 1.</strong> An example guided step.</p>
56
57<p>
58For each step in your multi-step task, extend
59{@link android.support.v17.leanback.app.GuidedStepFragment} and provide context information about
60the step and actions the user can take. Override
61{@link android.support.v17.leanback.app.GuidedStepFragment#onCreateGuidance onCreateGuidance()}
62and return a new
63{@link android.support.v17.leanback.widget.GuidanceStylist.Guidance} that contains context
64information, such as the step title, description, and icon.
65</p>
66
67<pre>
68&#64;Override
69public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
70    String title = getString(R.string.guidedstep_first_title);
71    String breadcrumb = getString(R.string.guidedstep_first_breadcrumb);
72    String description = getString(R.string.guidedstep_first_description);
73    Drawable icon = getActivity().getDrawable(R.drawable.guidedstep_main_icon_1);
74    return new GuidanceStylist.Guidance(title, description, breadcrumb, icon);
75}
76</pre>
77
78<p>
79Add your {@link android.support.v17.leanback.app.GuidedStepFragment} subclass to your desired
80activity by calling
81{@link android.support.v17.leanback.app.GuidedStepFragment#add GuidedStepFragment.add()}
82in your activity’s {@link android.app.Activity#onCreate onCreate()} method.
83
84If your activity contains only {@link android.support.v17.leanback.app.GuidedStepFragment}
85objects, use {@link android.support.v17.leanback.app.GuidedStepFragment#addAsRoot
86GuidedStepFragment.addAsRoot()} instead of
87{@link android.support.v17.leanback.app.GuidedStepFragment#add add()} to add the first
88{@link android.support.v17.leanback.app.GuidedStepFragment}. Using
89{@link android.support.v17.leanback.app.GuidedStepFragment#addAsRoot
90addAsRoot()} ensures that if the user presses the Back button on the TV remote when viewing
91the first {@link android.support.v17.leanback.app.GuidedStepFragment}, both the
92{@link android.support.v17.leanback.app.GuidedStepFragment} and the parent activity will close.
93</p>
94
95<p class="note"<strong>Note:</strong> Add
96{@link android.support.v17.leanback.app.GuidedStepFragment} objects programmatically
97and not in your layout XML files.</p>
98
99<h2 id="actions">Create and Handle User Actions</h2>
100
101<p>
102Add user actions by overriding
103{@link android.support.v17.leanback.app.GuidedStepFragment#onCreateActions onCreateActions()}.
104In your override, add a new {@link android.support.v17.leanback.widget.GuidedAction} for each
105action item, and provide the action string, description, and ID. Use
106{@link android.support.v17.leanback.widget.GuidedAction.Builder} to add new actions.
107</p>
108
109<pre>
110&#64;Override
111public void onCreateActions(List&lt;GuidedAction&gt; actions, Bundle savedInstanceState) {
112    // Add "Continue" user action for this step
113    actions.add(new GuidedAction.Builder()
114           .id(CONTINUE)
115           .title(getString(R.string.guidedstep_continue))
116           .description(getString(R.string.guidedstep_letsdoit))
117           .hasNext(true)
118           .build());
119...
120</pre>
121
122<p>
123Actions aren't limited to single-line selections. Here are additional types of
124actions you can create:
125</p>
126
127<ul>
128<li>
129Add an information label action by setting
130{@link android.support.v17.leanback.widget.GuidedAction.Builder#infoOnly infoOnly(true)}.
131If you set <code>infoOnly</code> to true, the user can't select the action. To
132provide additional information about user choices, use label actions.
133</li>
134<li>
135Add an editable text action by setting
136{@link android.support.v17.leanback.widget.GuidedAction.Builder#editable editable(true)}. If
137<code>editable</code> is true, when the action is selected the user can enter text using the
138remote or a connected keyboard. Override
139{@link android.support.v17.leanback.app.GuidedStepFragment#onGuidedActionEdited
140onGuidedActionEdited()} or
141{@code onGuidedActionEditedAndProceed()} to get the modified text the user entered.
142</li>
143<li>
144Add a set of actions that behave as checkable radio buttons by using
145{@link android.support.v17.leanback.widget.GuidedAction.Builder#checkSetId checkSetId()}
146with a common ID value to group actions into a set. All actions in the same list with the same
147check-set ID are considered linked. When the user selects one of the actions within that set, that
148action becomes checked, while all other actions become unchecked.
149</li>
150<li>
151Add a date-picker action by using
152{@code GuidedDatePickerAction.Builder}
153instead of
154{@link android.support.v17.leanback.widget.GuidedAction.Builder} in
155{@link android.support.v17.leanback.app.GuidedStepFragment#onCreateActions
156onCreateActions()}. Override
157{@link android.support.v17.leanback.app.GuidedStepFragment#onGuidedActionEdited
158onGuidedActionEdited()} or
159{@code onGuidedActionEditedAndProceed()} to get the modified date value the user entered.
160</li>
161<li>
162Add an action that uses subactions to let the user pick from an extended list of
163choices. Subactions are described in <a href="#subactions">Add subactions</a>.
164</li>
165<li>
166Add a button action that appears to the right of the actions list and is easily
167accessible. Button actions are described in <a href="#buttonactions">Add button
168actions</a>.</li>
169</ul>
170
171<p>
172You can also add a visual indicator&mdash;to indicate that selecting the action
173leads to a new step&mdash;by setting
174{@link android.support.v17.leanback.widget.GuidedAction#hasNext hasNext(true)}.
175For all the different attributes that you can set, see
176{@link android.support.v17.leanback.widget.GuidedAction}.
177</p>
178
179<p>
180To respond to actions, override
181{@link android.support.v17.leanback.app.GuidedStepFragment#onGuidedActionClicked
182onGuidedActionClicked()} and process the passed-in
183{@link android.support.v17.leanback.widget.GuidedAction}. Identify the selected action by
184examining {@link android.support.v17.leanback.widget.GuidedAction#getId GuidedAction.getId()}.
185</p>
186
187<h3 id="subactions">Add subactions</h3>
188
189<p>
190Some actions might require giving the user an additional set of choices. A
191{@link android.support.v17.leanback.widget.GuidedAction} can specify a list of
192subactions that get displayed as a drop-down list of child actions.
193</p>
194
195<img src="{@docRoot}images/training/tv/playback/guided-step-subaction.png"
196srcset="{@docRoot}images/training/tv/playback/guided-step-subaction.png 1x,
197{@docRoot}images/training/tv/playback/guided-step-subaction-2x.png 2x" />
198<p class="img-caption"><strong>Figure 2.</strong> Guided step subactions.</p>
199
200<p>
201The subaction list can contain regular actions or radio button actions, but
202not date-picker or editable text actions. Also, a subaction cannot have its own
203set of subactions as the system does not support more than one level of subactions.
204Deeply nested sets of actions create a poor user experience.
205</p>
206
207<p>
208To add subactions, first create and populate a list of
209{@link android.support.v17.leanback.widget.GuidedAction GuidedActions} that will
210act as subactions:
211</p>
212
213<pre>
214List&lt;GuidedAction&gt; subActions = new ArrayList&lt;GuidedAction&gt;();
215subActions.add(new GuidedAction.Builder()
216       .id(SUBACTION1)
217       .title(getString(R.string.guidedstep_subaction1_title))
218       .description(getString(R.string.guidedstep_subaction1_desc))
219       .build());
220...
221</pre>
222
223<p>
224In {@link android.support.v17.leanback.app.GuidedStepFragment#onCreateActions
225onCreateActions()}, create a top-level
226{@link android.support.v17.leanback.widget.GuidedAction} that will display the
227list of subactions when selected:
228</p>
229
230<pre>
231&#64;Override
232public void onCreateActions(List&lt;GuidedAction&gt; actions, Bundle savedInstanceState) {
233...
234    actions.add(new GuidedAction.Builder()
235           .id(SUBACTIONS)
236           .title(getString(R.string.guidedstep_subactions_title))
237           .description(getString(R.string.guidedstep_subactions_desc))
238           <b>.subActions(subActions)</b>
239           .build());
240...
241}
242</pre>
243
244<p>
245Finally, respond to subaction selections by overriding
246{@code onSubGuidedActionClicked()}:
247</p>
248
249<pre>
250&#64;Override
251public boolean onSubGuidedActionClicked(GuidedAction action) {
252   // Check for which action was clicked, and handle as needed
253   if (action.getId() == SUBACTION1) {
254       // Subaction 1 selected
255   }
256   // Return true to collapse the subactions drop-down list, or
257   // false to keep the drop-down list expanded.
258   return true;
259}
260</pre>
261
262<h3 id="buttonactions">Add button actions</h3>
263
264<p>
265If your guided step has a large list of actions, users may have to scroll through the list
266to access the most commonly used actions. Use button actions to separate
267commonly used actions from the action list. Button actions appear to the right
268of the action list and are easy to navigate to.
269</p>
270
271<img src="{@docRoot}images/training/tv/playback/guided-step-buttonaction.png"
272srcset="{@docRoot}images/training/tv/playback/guided-step-buttonaction.png 1x,
273{@docRoot}images/training/tv/playback/guided-step-buttonaction-2x.png 2x" />
274<p class="img-caption"><strong>Figure 3.</strong> Guided step button actions.</p>
275
276<p>
277Button actions are created and handled just like regular actions, but you create
278button actions in
279{@code onCreateButtonActions()} instead of
280{@link android.support.v17.leanback.app.GuidedStepFragment#onCreateActions
281onCreateActions()}. Respond to button actions in
282{@link android.support.v17.leanback.app.GuidedStepFragment#onGuidedActionClicked
283onGuidedActionClicked()}.
284</p>
285
286<p>
287Use button actions for simple actions, such as navigation actions between steps.
288Don't use the date-picker action or other editable actions as button actions.
289Also, button actions cannot have subactions.
290</p>
291
292<h2 id="sequence">Group Guided Steps Into a Guided Sequence</h2>
293
294<p>
295A {@link android.support.v17.leanback.app.GuidedStepFragment} represents a single step, however
296you might have several steps in an ordered sequence. Group multiple
297{@link android.support.v17.leanback.app.GuidedStepFragment} objects together by using
298{@link android.support.v17.leanback.app.GuidedStepFragment#add GuidedStepFragment.add()} to add
299the next step in the sequence to the fragment stack.
300</p>
301
302<pre>
303&#64;Override
304public void onGuidedActionClicked(GuidedAction action) {
305    FragmentManager fm = getFragmentManager();
306    if (action.getId() == CONTINUE) {
307       GuidedStepFragment.add(fm, new SecondStepFragment());
308    }
309...
310</pre>
311
312<p>
313If the user presses the Back button on the TV remote, the device shows the previous
314{@link android.support.v17.leanback.app.GuidedStepFragment} on the fragment stack. If you
315decide to provide your own {@link android.support.v17.leanback.widget.GuidedAction} that
316returns to the previous step, you can implement the Back behavior by calling
317{@link android.app.FragmentManager#popBackStack getFragmentManager().popBackStack()}.
318If you need to return the user to an even earlier step in the sequence, use
319{@code popBackStackToGuidedStepFragment()} to return to a specific
320{@link android.support.v17.leanback.app.GuidedStepFragment} in the fragment stack.
321</p>
322
323<p>
324When the user has finished the last step in the sequence, use
325{@code finishGuidedStepFragments()} to remove all
326{@link android.support.v17.leanback.app.GuidedStepFragment GuidedStepFragments}
327from the current stack and return to the original parent activity. If the
328first {@link android.support.v17.leanback.app.GuidedStepFragment} was added
329using {@link android.support.v17.leanback.app.GuidedStepFragment#addAsRoot
330addAsRoot()}, calling
331{@code finishGuidedStepFragments()} will also close the parent activity.
332</p>
333
334<h2 id="presentation">Customize Step Presentation</h2>
335
336<p>
337The {@link android.support.v17.leanback.app.GuidedStepFragment} class can use custom
338themes that control presentation aspects such as title text formatting or step transition
339animations. Custom themes must inherit from
340{@link android.support.v17.leanback.R.style#Theme_Leanback_GuidedStep}, and can provide
341overriding values for attributes defined in
342{@link android.support.v17.leanback.widget.GuidanceStylist} and
343{@link android.support.v17.leanback.widget.GuidedActionsStylist}.
344</p>
345
346<p>
347To apply a custom theme to your GuidedStepFragment, do one of the following:
348</p>
349
350<ul>
351<li>
352Apply the theme to the parent activity by setting the <code>android:theme</code> attribute to the
353activity element in the Android manifest. Setting this attribute applies the theme to all child
354views and is the easiest way to apply a custom theme if the parent activity contains only
355{@link android.support.v17.leanback.app.GuidedStepFragment} objects.
356</li>
357<li>
358If your activity already uses a custom theme and you don’t want to apply
359{@link android.support.v17.leanback.app.GuidedStepFragment} styles to other views in the activity,
360add the
361{@link android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedStepTheme}
362attribute to your existing custom activity theme. This attribute points to the custom theme that
363only the {@link android.support.v17.leanback.app.GuidedStepFragment} objects in your
364activity use.
365</li>
366<li>
367If you use {@link android.support.v17.leanback.app.GuidedStepFragment} objects in different
368activities that are part of the same overall multi-step task and want to use a consistent
369visual theme across all steps, override
370{@link android.support.v17.leanback.app.GuidedStepFragment#onProvideTheme
371GuidedStepFragment.onProvideTheme()} and return your custom theme.
372</li>
373</ul>
374
375<p>
376For more information on how to add styles and themes, see
377<a href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a>.
378</p>
379
380<p>
381The {@link android.support.v17.leanback.app.GuidedStepFragment} class uses special
382<em>stylist classes</em> to access and apply theme attributes.
383The {@link android.support.v17.leanback.widget.GuidanceStylist} class uses theme information
384to control presentation of the left guidance view, while the
385{@link android.support.v17.leanback.widget.GuidedActionsStylist} class uses theme information
386to control presentation of the right actions view.
387</p>
388
389<p>
390To customize the visual style of your steps beyond what theme customization can provide, subclass
391{@link android.support.v17.leanback.widget.GuidanceStylist} or
392{@link android.support.v17.leanback.widget.GuidedActionsStylist} and return your subclass in
393{@link android.support.v17.leanback.app.GuidedStepFragment#onCreateGuidanceStylist
394GuidedStepFragment.onCreateGuidanceStylist()} or
395{@link android.support.v17.leanback.app.GuidedStepFragment#onCreateActionsStylist
396GuidedStepFragment.onCreateActionsStylist()}.
397For details on what you can customize in these subclasses, see the documentation on
398{@link android.support.v17.leanback.widget.GuidanceStylist} and
399{@link android.support.v17.leanback.widget.GuidedActionsStylist}.
400</p>