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@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@Override 111public void onCreateActions(List<GuidedAction> 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—to indicate that selecting the action 173leads to a new step—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<GuidedAction> subActions = new ArrayList<GuidedAction>(); 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@Override 232public void onCreateActions(List<GuidedAction> 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@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@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>