1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.leanback; 18 19 import android.app.Activity; 20 import android.app.Fragment; 21 import android.app.FragmentManager; 22 import android.content.Context; 23 import android.content.res.Configuration; 24 import android.graphics.drawable.Drawable; 25 import android.os.Bundle; 26 import android.text.InputType; 27 import android.text.TextUtils; 28 import android.util.Log; 29 import android.view.LayoutInflater; 30 import android.view.View; 31 import android.view.ViewGroup; 32 import android.view.inputmethod.EditorInfo; 33 34 import androidx.core.content.res.ResourcesCompat; 35 import androidx.leanback.app.GuidedStepFragment; 36 import androidx.leanback.widget.GuidanceStylist; 37 import androidx.leanback.widget.GuidanceStylist.Guidance; 38 import androidx.leanback.widget.GuidedAction; 39 import androidx.leanback.widget.GuidedActionsStylist; 40 import androidx.leanback.widget.GuidedDatePickerAction; 41 42 import java.util.ArrayList; 43 import java.util.Calendar; 44 import java.util.List; 45 46 /** 47 * Activity that showcases different aspects of GuidedStepFragments. 48 */ 49 public class GuidedStepActivity extends Activity { 50 51 private static final int BACK = 2; 52 53 private static final int FIRST_NAME = 3; 54 private static final int LAST_NAME = 4; 55 private static final int PASSWORD = 5; 56 private static final int PAYMENT = 6; 57 private static final int NEW_PAYMENT = 7; 58 private static final int PAYMENT_EXPIRE = 8; 59 private static final int REFRESH = 9; 60 61 private static final long RADIO_ID_BASE = 0; 62 private static final long CHECKBOX_ID_BASE = 100; 63 64 private static final long DEFAULT_OPTION = RADIO_ID_BASE; 65 66 private static final String[] OPTION_NAMES = { "Option A", "Option B", "Option C" }; 67 private static final String[] OPTION_DESCRIPTIONS = { "Here's one thing you can do", 68 "Here's another thing you can do", "Here's one more thing you can do" }; 69 70 private static final String TAG = GuidedStepActivity.class.getSimpleName(); 71 72 @Override 73 protected void onCreate(Bundle savedInstanceState) { 74 Log.v(TAG, "onCreate"); 75 super.onCreate(savedInstanceState); 76 setContentView(R.layout.guided_step_activity); 77 if (savedInstanceState == null) { 78 GuidedStepFragment.addAsRoot(this, new FirstStepFragment(), R.id.lb_guidedstep_host); 79 } 80 } 81 82 @Override 83 public void onConfigurationChanged(Configuration newConfig) { 84 Log.v(TAG, "onConfigurationChanged"); 85 super.onConfigurationChanged(newConfig); 86 } 87 88 @Override 89 protected void onSaveInstanceState(Bundle outState) { 90 Log.v(TAG, "onSaveInstanceState"); 91 super.onSaveInstanceState(outState); 92 } 93 94 @Override 95 protected void onRestoreInstanceState(Bundle savedInstanceState) { 96 Log.v(TAG, "onRestoreInstanceState"); 97 super.onRestoreInstanceState(savedInstanceState); 98 } 99 100 private static GuidedAction addAction(List<GuidedAction> actions, long id, String title, 101 String desc) { 102 GuidedAction action; 103 actions.add(action = new GuidedAction.Builder(null) 104 .id(id) 105 .title(title) 106 .description(desc) 107 .build()); 108 return action; 109 } 110 111 private static GuidedAction addAction(List<GuidedAction> actions, long id, String title, 112 String desc, List<GuidedAction> subActions) { 113 GuidedAction action; 114 actions.add(action = new GuidedAction.Builder(null) 115 .id(id) 116 .title(title) 117 .description(desc) 118 .subActions(subActions) 119 .build()); 120 return action; 121 } 122 123 private static GuidedAction addEditableAction(Context context, List<GuidedAction> actions, 124 long id, String title, String desc) { 125 GuidedAction action; 126 actions.add(action = new GuidedAction.Builder(context) 127 .id(id) 128 .title(title) 129 .description(desc) 130 .editable(true) 131 .icon(R.drawable.lb_ic_search_mic) 132 .build()); 133 return action; 134 } 135 136 private static GuidedAction addEditableAction(List<GuidedAction> actions, long id, String title, 137 String editTitle, String desc) { 138 GuidedAction action; 139 actions.add(action = new GuidedAction.Builder(null) 140 .id(id) 141 .title(title) 142 .editTitle(editTitle) 143 .description(desc) 144 .editable(true) 145 .build()); 146 return action; 147 } 148 149 private static GuidedAction addEditableAction(List<GuidedAction> actions, long id, String title, 150 String editTitle, int editInputType, String desc, String editDesc) { 151 GuidedAction action; 152 actions.add(action = new GuidedAction.Builder(null) 153 .id(id) 154 .title(title) 155 .editTitle(editTitle) 156 .editInputType(editInputType) 157 .description(desc) 158 .editDescription(editDesc) 159 .editable(true) 160 .build()); 161 return action; 162 } 163 164 private static GuidedDatePickerAction addDatePickerAction(List<GuidedAction> actions, long id, 165 String title) { 166 GuidedDatePickerAction action; 167 actions.add(action = new GuidedDatePickerAction.Builder(null) 168 .id(id) 169 .title(title) 170 .datePickerFormat("MY") 171 .build()); 172 return action; 173 } 174 175 private static GuidedAction addEditableDescriptionAction(List<GuidedAction> actions, long id, 176 String title, String desc, String editDescription, int descriptionEditInputType) { 177 GuidedAction action; 178 actions.add(action = new GuidedAction.Builder(null) 179 .id(id) 180 .title(title) 181 .description(desc) 182 .editDescription(editDescription) 183 .descriptionEditInputType(descriptionEditInputType) 184 .descriptionEditable(true) 185 .build()); 186 return action; 187 } 188 189 private static GuidedAction addCheckedAction(List<GuidedAction> actions, long id, 190 String title, String desc, int checkSetId) { 191 GuidedAction action; 192 actions.add(action = new GuidedAction.Builder(null) 193 .id(id) 194 .title(title) 195 .description(desc) 196 .checkSetId(checkSetId) 197 .build()); 198 return action; 199 } 200 201 public static class FirstStepFragment extends GuidedStepFragment { 202 203 @Override 204 public int onProvideTheme() { 205 return R.style.Theme_Example_Leanback_GuidedStep_First; 206 } 207 208 @Override 209 public Guidance onCreateGuidance(Bundle savedInstanceState) { 210 String title = getString(R.string.guidedstep_first_title); 211 String breadcrumb = getString(R.string.guidedstep_first_breadcrumb); 212 String description = getString(R.string.guidedstep_first_description); 213 final Context context = getActivity(); 214 Drawable icon = ResourcesCompat.getDrawable(context.getResources(), 215 R.drawable.ic_main_icon, context.getTheme()); 216 return new Guidance(title, description, breadcrumb, icon); 217 } 218 219 @Override 220 public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { 221 Context context = getActivity(); 222 actions.add(new GuidedAction.Builder(context) 223 .clickAction(GuidedAction.ACTION_ID_CONTINUE) 224 .description("Let's do it") 225 .build()); 226 actions.add(new GuidedAction.Builder(context) 227 .id(REFRESH) 228 .title("Refresh") 229 .build()); 230 actions.add(new GuidedAction.Builder(context) 231 .clickAction(GuidedAction.ACTION_ID_CANCEL) 232 .description("Never mind") 233 .build()); 234 } 235 236 @Override 237 public void onGuidedActionClicked(GuidedAction action) { 238 FragmentManager fm = getFragmentManager(); 239 if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) { 240 GuidedStepFragment.add(fm, new SecondStepFragment(), R.id.lb_guidedstep_host); 241 } else if (action.getId() == REFRESH) { 242 // swap actions position and change content: 243 Context context = getActivity(); 244 ArrayList<GuidedAction> newActions = new ArrayList(); 245 newActions.add(new GuidedAction.Builder(context) 246 .id(REFRESH) 247 .title("Refresh done") 248 .build()); 249 newActions.add(new GuidedAction.Builder(context) 250 .clickAction(GuidedAction.ACTION_ID_CONTINUE) 251 .description("Let's do it") 252 .build()); 253 newActions.add(new GuidedAction.Builder(context) 254 .clickAction(GuidedAction.ACTION_ID_CANCEL) 255 .description("Never mind") 256 .build()); 257 //setActionsDiffCallback(null); 258 setActions(newActions); 259 } else if (action.getId() == GuidedAction.ACTION_ID_CANCEL){ 260 finishGuidedStepFragments(); 261 } 262 } 263 } 264 265 public interface NewPaymentFragmentTarget { 266 void onNewPaymentFragmentStarted(); 267 void onNewPaymentAdded(int selection); 268 } 269 270 static ArrayList<String> sCards = new ArrayList<String>(); 271 static int sSelectedCard = -1; 272 static { 273 sCards.add("Visa-1234"); 274 sCards.add("Master-4321"); 275 } 276 277 public static class NewPaymentStepFragment extends GuidedStepFragment { 278 279 NewPaymentFragmentTarget mNewPaymentTarget; 280 281 @Override 282 public void onCreate(Bundle savedInstance) { 283 super.onCreate(savedInstance); 284 Fragment targetFragment = getTargetFragment(); 285 if (targetFragment instanceof NewPaymentFragmentTarget) { 286 mNewPaymentTarget = ((NewPaymentFragmentTarget) targetFragment); 287 mNewPaymentTarget.onNewPaymentFragmentStarted(); 288 } 289 } 290 291 @Override 292 public Guidance onCreateGuidance(Bundle savedInstanceState) { 293 String title = getString(R.string.guidedstep_newpayment_title); 294 String breadcrumb = getString(R.string.guidedstep_newpayment_breadcrumb); 295 String description = getString(R.string.guidedstep_newpayment_description); 296 final Context context = getActivity(); 297 Drawable icon = ResourcesCompat.getDrawable(context.getResources(), 298 R.drawable.ic_main_icon, context.getTheme()); 299 return new Guidance(title, description, breadcrumb, icon); 300 } 301 302 @Override 303 public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { 304 addEditableAction(actions, NEW_PAYMENT, "Input credit card number", "", 305 InputType.TYPE_CLASS_NUMBER, 306 "Input credit card number", "Input credit card number"); 307 addDatePickerAction(actions, PAYMENT_EXPIRE, "Exp:"); 308 } 309 310 @Override 311 public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) { 312 Context context = getActivity(); 313 actions.add(new GuidedAction.Builder(context).clickAction(GuidedAction.ACTION_ID_OK) 314 .build()); 315 actions.get(actions.size() - 1).setEnabled(false); 316 } 317 318 @Override 319 public void onGuidedActionClicked(GuidedAction action) { 320 if (action.getId() == GuidedAction.ACTION_ID_OK) { 321 CharSequence desc = findActionById(NEW_PAYMENT).getDescription(); 322 String cardNumber = desc.subSequence(desc.length() - 4, desc.length()).toString(); 323 String card; 324 if ((Integer.parseInt(cardNumber) & 1) == 0) { 325 card = "Visa "+cardNumber; 326 } else { 327 card = "Master "+cardNumber; 328 } 329 int selection = sCards.size(); 330 sCards.add(card); 331 if (mNewPaymentTarget != null) { 332 mNewPaymentTarget.onNewPaymentAdded(selection); 333 } 334 popBackStackToGuidedStepFragment(NewPaymentStepFragment.class, 335 FragmentManager.POP_BACK_STACK_INCLUSIVE); 336 } 337 } 338 339 @Override 340 public long onGuidedActionEditedAndProceed(GuidedAction action) { 341 if (action.getId() == NEW_PAYMENT) { 342 CharSequence editTitle = action.getEditTitle(); 343 if (isCardNumberValid(editTitle)) { 344 editTitle = editTitle.subSequence(editTitle.length() - 4, editTitle.length()); 345 action.setDescription("Visa XXXX-XXXX-XXXX-" + editTitle); 346 updateOkButton(isExpDateValid(findActionById(PAYMENT_EXPIRE))); 347 return GuidedAction.ACTION_ID_NEXT; 348 } else if (editTitle.length() == 0) { 349 action.setDescription("Input credit card number"); 350 updateOkButton(false); 351 return GuidedAction.ACTION_ID_CURRENT; 352 } else { 353 action.setDescription("Error credit card number"); 354 updateOkButton(false); 355 return GuidedAction.ACTION_ID_CURRENT; 356 } 357 } else if (action.getId() == PAYMENT_EXPIRE) { 358 updateOkButton(isExpDateValid(action) && 359 isCardNumberValid(findActionById(NEW_PAYMENT).getEditTitle())); 360 } 361 return GuidedAction.ACTION_ID_NEXT; 362 } 363 364 boolean isCardNumberValid(CharSequence number) { 365 return TextUtils.isDigitsOnly(number) && number.length() == 16; 366 } 367 368 boolean isExpDateValid(GuidedAction action) { 369 long date = ((GuidedDatePickerAction) action).getDate(); 370 Calendar c = Calendar.getInstance(); 371 c.setTimeInMillis(date); 372 return Calendar.getInstance().before(c); 373 } 374 375 void updateOkButton(boolean enabled) { 376 findButtonActionById(GuidedAction.ACTION_ID_OK).setEnabled(enabled); 377 notifyButtonActionChanged(findButtonActionPositionById(GuidedAction.ACTION_ID_OK)); 378 } 379 } 380 381 public static class SecondStepFragment extends GuidedStepFragment 382 implements NewPaymentFragmentTarget { 383 384 385 boolean mExpandPaymentListInOnCreateView; 386 387 @Override 388 public void onNewPaymentAdded(int selection) { 389 // if a new payment is added, we dont need expand the sub actions list. 390 mExpandPaymentListInOnCreateView = false; 391 sSelectedCard = selection; 392 updatePaymentAction(findActionById(PAYMENT)); 393 findButtonActionById(GuidedAction.ACTION_ID_CONTINUE).setEnabled(sSelectedCard != -1); 394 } 395 396 @Override 397 public void onNewPaymentFragmentStarted() { 398 // if a new payment fragment is opened, when come back we should expand the payment 399 // sub actions list unless user created a new payment in onNewPaymentAdded 400 mExpandPaymentListInOnCreateView = true; 401 } 402 403 @Override 404 public GuidedActionsStylist onCreateActionsStylist() { 405 return new GuidedActionsStylist() { 406 @Override 407 protected void setupImeOptions(GuidedActionsStylist.ViewHolder vh, 408 GuidedAction action) { 409 if (action.getId() == PASSWORD) { 410 vh.getEditableDescriptionView().setImeActionLabel("Confirm!", 411 EditorInfo.IME_ACTION_DONE); 412 } else { 413 super.setupImeOptions(vh, action); 414 } 415 } 416 }; 417 } 418 419 @Override 420 public Guidance onCreateGuidance(Bundle savedInstanceState) { 421 String title = getString(R.string.guidedstep_second_title); 422 String breadcrumb = getString(R.string.guidedstep_second_breadcrumb); 423 String description = getString(R.string.guidedstep_second_description); 424 final Context context = getActivity(); 425 Drawable icon = ResourcesCompat.getDrawable(context.getResources(), 426 R.drawable.ic_main_icon, context.getTheme()); 427 return new Guidance(title, description, breadcrumb, icon); 428 } 429 430 @Override 431 public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { 432 addEditableAction(getActivity(), actions, FIRST_NAME, "Pat", "Your first name"); 433 addEditableAction(getActivity(), actions, LAST_NAME, "Smith", "Your last name"); 434 List<GuidedAction> subActions = new ArrayList<GuidedAction>(); 435 updatePaymentAction(addAction(actions, PAYMENT, "Select Payment", "", subActions)); 436 addEditableDescriptionAction(actions, PASSWORD, "Password", "", "", 437 InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); 438 } 439 440 @Override 441 public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) { 442 actions.add(new GuidedAction.Builder(getActivity()) 443 .clickAction(GuidedAction.ACTION_ID_CONTINUE) 444 .description("Continue") 445 .enabled(isPasswordValid() && isPaymentValid()) 446 .build()); 447 } 448 449 @Override 450 public void onGuidedActionClicked(GuidedAction action) { 451 if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) { 452 FragmentManager fm = getFragmentManager(); 453 GuidedStepFragment.add(fm, new ThirdStepFragment(), R.id.lb_guidedstep_host); 454 } 455 } 456 457 void updatePaymentAction(GuidedAction paymentAction) { 458 List<GuidedAction> subActions = paymentAction.getSubActions(); 459 subActions.clear(); 460 for (int i = 0; i < sCards.size(); i++) { 461 addCheckedAction(subActions, -1, sCards.get(i), "", 462 GuidedAction.DEFAULT_CHECK_SET_ID); 463 if (i == sSelectedCard) { 464 subActions.get(i).setChecked(true); 465 } 466 } 467 addAction(subActions, NEW_PAYMENT, "Add New Card", ""); 468 paymentAction.setDescription(sSelectedCard == -1 ? "" : sCards.get(sSelectedCard)); 469 } 470 471 @Override 472 public long onGuidedActionEditedAndProceed(GuidedAction action) { 473 if (action.getId() == PASSWORD) { 474 CharSequence password = action.getEditDescription(); 475 if (password.length() > 0) { 476 if (isPaymentValid()) { 477 updateContinue(true); 478 return GuidedAction.ACTION_ID_NEXT; 479 } else { 480 updateContinue(false); 481 return GuidedAction.ACTION_ID_CURRENT; 482 } 483 } else { 484 updateContinue(false); 485 return GuidedAction.ACTION_ID_CURRENT; 486 } 487 } 488 return GuidedAction.ACTION_ID_NEXT; 489 } 490 491 @Override 492 public boolean onSubGuidedActionClicked(GuidedAction action) { 493 if (action.isChecked()) { 494 String payment = action.getTitle().toString(); 495 for (int i = 0; i < sCards.size(); i++) { 496 if (payment.equals(sCards.get(i))) { 497 sSelectedCard = i; 498 findActionById(PAYMENT).setDescription(payment); 499 notifyActionChanged(findActionPositionById(PAYMENT)); 500 updateContinue(isPasswordValid()); 501 break; 502 } 503 } 504 return true; 505 } else { 506 FragmentManager fm = getFragmentManager(); 507 NewPaymentStepFragment newPaymentFragment = new NewPaymentStepFragment(); 508 newPaymentFragment.setTargetFragment(this, 0); 509 GuidedStepFragment.add(fm, newPaymentFragment, R.id.lb_guidedstep_host); 510 return false; 511 } 512 } 513 514 @Override 515 public View onCreateView(LayoutInflater inflater, ViewGroup container, 516 Bundle savedInstanceState) { 517 View view = super.onCreateView(inflater, container, savedInstanceState); 518 if (mExpandPaymentListInOnCreateView) { 519 expandAction(findActionById(PAYMENT), false); 520 } 521 return view; 522 } 523 524 boolean isPaymentValid() { 525 CharSequence paymentType = findActionById(PAYMENT).getDescription(); 526 return (paymentType.length() >= 4 && 527 paymentType.subSequence(0, 4).toString().equals("Visa")) || 528 (paymentType.length() >= 6 && 529 paymentType.subSequence(0, 6).toString().equals("Master")); 530 } 531 532 boolean isPasswordValid() { 533 return findActionById(PASSWORD).getEditDescription().length() > 0; 534 } 535 536 void updateContinue(boolean enabled) { 537 findButtonActionById(GuidedAction.ACTION_ID_CONTINUE).setEnabled(enabled); 538 notifyButtonActionChanged(findButtonActionPositionById( 539 GuidedAction.ACTION_ID_CONTINUE)); 540 } 541 } 542 543 public static class ThirdStepFragment extends GuidedStepFragment { 544 545 private long mSelectedOption = DEFAULT_OPTION; 546 547 @Override 548 public Guidance onCreateGuidance(Bundle savedInstanceState) { 549 String title = getString(R.string.guidedstep_third_title); 550 String breadcrumb = getString(R.string.guidedstep_third_breadcrumb); 551 String description = getString(R.string.guidedstep_third_description); 552 final Context context = getActivity(); 553 Drawable icon = ResourcesCompat.getDrawable(context.getResources(), 554 R.drawable.ic_main_icon, context.getTheme()); 555 return new Guidance(title, description, breadcrumb, icon); 556 } 557 558 @Override 559 public GuidanceStylist onCreateGuidanceStylist() { 560 return new GuidanceStylist() { 561 @Override 562 public int onProvideLayoutId() { 563 return R.layout.guidedstep_second_guidance; 564 } 565 }; 566 } 567 568 @Override 569 public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { 570 String desc = "The description can be quite long as well. " 571 + "Just be sure to set multilineDescription to true in the GuidedAction." 572 + "For testing purpose we make this line even longer since " 573 + "multilineDescriptionMinLines will be set to 2."; 574 actions.add(new GuidedAction.Builder(getActivity()) 575 .title("Note that Guided Actions can have titles that are quite long.") 576 .description(desc) 577 .multilineDescription(true) 578 .infoOnly(true) 579 .enabled(true) 580 .focusable(false) 581 .build()); 582 for (int i = 0; i < OPTION_NAMES.length; i++) { 583 addCheckedAction(actions, RADIO_ID_BASE + i, OPTION_NAMES[i], 584 OPTION_DESCRIPTIONS[i], GuidedAction.DEFAULT_CHECK_SET_ID); 585 if (i == DEFAULT_OPTION) { 586 actions.get(actions.size() -1).setChecked(true); 587 } 588 } 589 for (int i = 0; i < OPTION_NAMES.length; i++) { 590 addCheckedAction(actions, CHECKBOX_ID_BASE + i, OPTION_NAMES[i], 591 OPTION_DESCRIPTIONS[i], GuidedAction.CHECKBOX_CHECK_SET_ID); 592 } 593 } 594 595 @Override 596 public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) { 597 actions.add(new GuidedAction.Builder(getActivity()) 598 .clickAction(GuidedAction.ACTION_ID_CONTINUE) 599 .build()); 600 } 601 602 @Override 603 public void onGuidedActionClicked(GuidedAction action) { 604 if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) { 605 FragmentManager fm = getFragmentManager(); 606 FourthStepFragment f = new FourthStepFragment(); 607 Bundle arguments = new Bundle(); 608 arguments.putLong(FourthStepFragment.EXTRA_OPTION, mSelectedOption); 609 f.setArguments(arguments); 610 GuidedStepFragment.add(fm, f, R.id.lb_guidedstep_host); 611 } else if (action.getCheckSetId() == GuidedAction.DEFAULT_CHECK_SET_ID) { 612 mSelectedOption = action.getId(); 613 } 614 } 615 616 } 617 618 public static class FourthStepFragment extends GuidedStepFragment { 619 public static final String EXTRA_OPTION = "extra_option"; 620 621 public FourthStepFragment() { 622 } 623 624 public long getOption() { 625 Bundle b = getArguments(); 626 if (b == null) return 0; 627 return b.getLong(EXTRA_OPTION, 0); 628 } 629 630 @Override 631 public Guidance onCreateGuidance(Bundle savedInstanceState) { 632 String title = getString(R.string.guidedstep_fourth_title); 633 String breadcrumb = getString(R.string.guidedstep_fourth_breadcrumb); 634 String description = "You chose: " + OPTION_NAMES[(int) getOption()]; 635 final Context context = getActivity(); 636 Drawable icon = ResourcesCompat.getDrawable(context.getResources(), 637 R.drawable.ic_main_icon, context.getTheme()); 638 return new Guidance(title, description, breadcrumb, icon); 639 } 640 641 @Override 642 public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { 643 actions.add(new GuidedAction.Builder(getActivity()) 644 .clickAction(GuidedAction.ACTION_ID_FINISH) 645 .description("All Done...") 646 .build()); 647 addAction(actions, BACK, "Start Over", "Let's try this again..."); 648 } 649 650 @Override 651 public void onGuidedActionClicked(GuidedAction action) { 652 if (action.getId() == GuidedAction.ACTION_ID_FINISH) { 653 finishGuidedStepFragments(); 654 } else if (action.getId() == BACK) { 655 // pop 4, 3, 2 656 popBackStackToGuidedStepFragment(SecondStepFragment.class, 657 FragmentManager.POP_BACK_STACK_INCLUSIVE); 658 } 659 } 660 661 } 662 663 } 664