1 page.title=Adding a Guided Step 2 page.tags=tv,guided step,GuidedStepFragment,GuidedAction 3 page.keywords=tv,GuidedStepFragment,GuidedAction 4 helpoutsWidget=true 5 6 trainingnavtop=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> 28 Your application might have multi-step tasks for users. For example, your app might need to guide 29 users through purchasing additional content, or setting up a complex configuration setting, or 30 simply confirming a decision. All of these tasks require walking users through one or more ordered 31 steps or decisions. 32 </p> 33 34 <p> 35 The <a href= 36 "{@docRoot}tools/support-library/features.html#v17-leanback">v17 Leanback support library</a> 37 provides 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 39 of decisions to accomplish a task. {@link android.support.v17.leanback.app.GuidedStepFragment} uses 40 TV 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> 46 A {@link android.support.v17.leanback.app.GuidedStepFragment} represents a single step in a series 47 of 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 49 list of possible actions or decisions for this step. 50 </p> 51 52 <img src="{@docRoot}images/training/tv/playback/guided-step-screen.png" 53 srcset="{@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> 58 For each step in your multi-step task, extend 59 {@link android.support.v17.leanback.app.GuidedStepFragment} and provide context information about 60 the step and actions the user can take. Override 61 {@link android.support.v17.leanback.app.GuidedStepFragment#onCreateGuidance onCreateGuidance()} 62 and return a new 63 {@link android.support.v17.leanback.widget.GuidanceStylist.Guidance} that contains context 64 information, such as the step title, description, and icon. 65 </p> 66 67 <pre> 68 @Override 69 public 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> 79 Add your {@link android.support.v17.leanback.app.GuidedStepFragment} subclass to your desired 80 activity by calling 81 {@link android.support.v17.leanback.app.GuidedStepFragment#add GuidedStepFragment.add()} 82 in your activitys {@link android.app.Activity#onCreate onCreate()} method. 83 84 If your activity contains only {@link android.support.v17.leanback.app.GuidedStepFragment} 85 objects, use {@link android.support.v17.leanback.app.GuidedStepFragment#addAsRoot 86 GuidedStepFragment.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 90 addAsRoot()} ensures that if the user presses the Back button on the TV remote when viewing 91 the 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 97 and not in your layout XML files.</p> 98 99 <h2 id="actions">Create and Handle User Actions</h2> 100 101 <p> 102 Add user actions by overriding 103 {@link android.support.v17.leanback.app.GuidedStepFragment#onCreateActions onCreateActions()}. 104 In your override, add a new {@link android.support.v17.leanback.widget.GuidedAction} for each 105 action 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 111 public 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> 123 Actions aren't limited to single-line selections. Here are additional types of 124 actions you can create: 125 </p> 126 127 <ul> 128 <li> 129 Add an information label action by setting 130 {@link android.support.v17.leanback.widget.GuidedAction.Builder#infoOnly infoOnly(true)}. 131 If you set <code>infoOnly</code> to true, the user can't select the action. To 132 provide additional information about user choices, use label actions. 133 </li> 134 <li> 135 Add 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 138 remote or a connected keyboard. Override 139 {@link android.support.v17.leanback.app.GuidedStepFragment#onGuidedActionEdited 140 onGuidedActionEdited()} or 141 {@code onGuidedActionEditedAndProceed()} to get the modified text the user entered. 142 </li> 143 <li> 144 Add a set of actions that behave as checkable radio buttons by using 145 {@link android.support.v17.leanback.widget.GuidedAction.Builder#checkSetId checkSetId()} 146 with a common ID value to group actions into a set. All actions in the same list with the same 147 check-set ID are considered linked. When the user selects one of the actions within that set, that 148 action becomes checked, while all other actions become unchecked. 149 </li> 150 <li> 151 Add a date-picker action by using 152 {@code GuidedDatePickerAction.Builder} 153 instead of 154 {@link android.support.v17.leanback.widget.GuidedAction.Builder} in 155 {@link android.support.v17.leanback.app.GuidedStepFragment#onCreateActions 156 onCreateActions()}. Override 157 {@link android.support.v17.leanback.app.GuidedStepFragment#onGuidedActionEdited 158 onGuidedActionEdited()} or 159 {@code onGuidedActionEditedAndProceed()} to get the modified date value the user entered. 160 </li> 161 <li> 162 Add an action that uses subactions to let the user pick from an extended list of 163 choices. Subactions are described in <a href="#subactions">Add subactions</a>. 164 </li> 165 <li> 166 Add a button action that appears to the right of the actions list and is easily 167 accessible. Button actions are described in <a href="#buttonactions">Add button 168 actions</a>.</li> 169 </ul> 170 171 <p> 172 You can also add a visual indicator—to indicate that selecting the action 173 leads to a new step—by setting 174 {@link android.support.v17.leanback.widget.GuidedAction#hasNext hasNext(true)}. 175 For all the different attributes that you can set, see 176 {@link android.support.v17.leanback.widget.GuidedAction}. 177 </p> 178 179 <p> 180 To respond to actions, override 181 {@link android.support.v17.leanback.app.GuidedStepFragment#onGuidedActionClicked 182 onGuidedActionClicked()} and process the passed-in 183 {@link android.support.v17.leanback.widget.GuidedAction}. Identify the selected action by 184 examining {@link android.support.v17.leanback.widget.GuidedAction#getId GuidedAction.getId()}. 185 </p> 186 187 <h3 id="subactions">Add subactions</h3> 188 189 <p> 190 Some 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 192 subactions 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" 196 srcset="{@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> 201 The subaction list can contain regular actions or radio button actions, but 202 not date-picker or editable text actions. Also, a subaction cannot have its own 203 set of subactions as the system does not support more than one level of subactions. 204 Deeply nested sets of actions create a poor user experience. 205 </p> 206 207 <p> 208 To add subactions, first create and populate a list of 209 {@link android.support.v17.leanback.widget.GuidedAction GuidedActions} that will 210 act as subactions: 211 </p> 212 213 <pre> 214 List<GuidedAction> subActions = new ArrayList<GuidedAction>(); 215 subActions.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> 224 In {@link android.support.v17.leanback.app.GuidedStepFragment#onCreateActions 225 onCreateActions()}, create a top-level 226 {@link android.support.v17.leanback.widget.GuidedAction} that will display the 227 list of subactions when selected: 228 </p> 229 230 <pre> 231 @Override 232 public 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> 245 Finally, respond to subaction selections by overriding 246 {@code onSubGuidedActionClicked()}: 247 </p> 248 249 <pre> 250 @Override 251 public 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> 265 If your guided step has a large list of actions, users may have to scroll through the list 266 to access the most commonly used actions. Use button actions to separate 267 commonly used actions from the action list. Button actions appear to the right 268 of the action list and are easy to navigate to. 269 </p> 270 271 <img src="{@docRoot}images/training/tv/playback/guided-step-buttonaction.png" 272 srcset="{@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> 277 Button actions are created and handled just like regular actions, but you create 278 button actions in 279 {@code onCreateButtonActions()} instead of 280 {@link android.support.v17.leanback.app.GuidedStepFragment#onCreateActions 281 onCreateActions()}. Respond to button actions in 282 {@link android.support.v17.leanback.app.GuidedStepFragment#onGuidedActionClicked 283 onGuidedActionClicked()}. 284 </p> 285 286 <p> 287 Use button actions for simple actions, such as navigation actions between steps. 288 Don't use the date-picker action or other editable actions as button actions. 289 Also, button actions cannot have subactions. 290 </p> 291 292 <h2 id="sequence">Group Guided Steps Into a Guided Sequence</h2> 293 294 <p> 295 A {@link android.support.v17.leanback.app.GuidedStepFragment} represents a single step, however 296 you 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 299 the next step in the sequence to the fragment stack. 300 </p> 301 302 <pre> 303 @Override 304 public 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> 313 If 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 315 decide to provide your own {@link android.support.v17.leanback.widget.GuidedAction} that 316 returns to the previous step, you can implement the Back behavior by calling 317 {@link android.app.FragmentManager#popBackStack getFragmentManager().popBackStack()}. 318 If 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> 324 When 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} 327 from the current stack and return to the original parent activity. If the 328 first {@link android.support.v17.leanback.app.GuidedStepFragment} was added 329 using {@link android.support.v17.leanback.app.GuidedStepFragment#addAsRoot 330 addAsRoot()}, calling 331 {@code finishGuidedStepFragments()} will also close the parent activity. 332 </p> 333 334 <h2 id="presentation">Customize Step Presentation</h2> 335 336 <p> 337 The {@link android.support.v17.leanback.app.GuidedStepFragment} class can use custom 338 themes that control presentation aspects such as title text formatting or step transition 339 animations. Custom themes must inherit from 340 {@link android.support.v17.leanback.R.style#Theme_Leanback_GuidedStep}, and can provide 341 overriding 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> 347 To apply a custom theme to your GuidedStepFragment, do one of the following: 348 </p> 349 350 <ul> 351 <li> 352 Apply the theme to the parent activity by setting the <code>android:theme</code> attribute to the 353 activity element in the Android manifest. Setting this attribute applies the theme to all child 354 views 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> 358 If your activity already uses a custom theme and you dont want to apply 359 {@link android.support.v17.leanback.app.GuidedStepFragment} styles to other views in the activity, 360 add the 361 {@link android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedStepTheme} 362 attribute to your existing custom activity theme. This attribute points to the custom theme that 363 only the {@link android.support.v17.leanback.app.GuidedStepFragment} objects in your 364 activity use. 365 </li> 366 <li> 367 If you use {@link android.support.v17.leanback.app.GuidedStepFragment} objects in different 368 activities that are part of the same overall multi-step task and want to use a consistent 369 visual theme across all steps, override 370 {@link android.support.v17.leanback.app.GuidedStepFragment#onProvideTheme 371 GuidedStepFragment.onProvideTheme()} and return your custom theme. 372 </li> 373 </ul> 374 375 <p> 376 For 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> 381 The {@link android.support.v17.leanback.app.GuidedStepFragment} class uses special 382 <em>stylist classes</em> to access and apply theme attributes. 383 The {@link android.support.v17.leanback.widget.GuidanceStylist} class uses theme information 384 to control presentation of the left guidance view, while the 385 {@link android.support.v17.leanback.widget.GuidedActionsStylist} class uses theme information 386 to control presentation of the right actions view. 387 </p> 388 389 <p> 390 To 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 394 GuidedStepFragment.onCreateGuidanceStylist()} or 395 {@link android.support.v17.leanback.app.GuidedStepFragment#onCreateActionsStylist 396 GuidedStepFragment.onCreateActionsStylist()}. 397 For 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>