GuidedAction.java revision bc62e0bf64bc727e7fe983ee1ffe07e266f143c8
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14package android.support.v17.leanback.widget; 15 16import android.support.annotation.DrawableRes; 17import android.support.annotation.StringRes; 18import android.support.v17.leanback.R; 19import android.support.v4.content.ContextCompat; 20 21import android.content.Context; 22import android.content.Intent; 23import android.graphics.drawable.Drawable; 24import android.text.InputType; 25 26import java.util.List; 27 28/** 29 * A data class which represents an action within a {@link 30 * android.support.v17.leanback.app.GuidedStepFragment}. GuidedActions contain at minimum a title 31 * and a description, and typically also an icon. 32 * <p> 33 * A GuidedAction typically represents a single action a user may take, but may also represent a 34 * possible choice out of a group of mutually exclusive choices (similar to radio buttons), or an 35 * information-only label (in which case the item cannot be clicked). 36 * <p> 37 * GuidedActions may optionally be checked. They may also indicate that they will request further 38 * user input on selection, in which case they will be displayed with a chevron indicator. 39 * <p> 40 * GuidedAction recommends to use {@link Builder}. When application subclass GuidedAction, it 41 * can subclass {@link BuilderBase}, implement {@link BuilderBase#build()} where it should 42 * call {@link BuilderBase#applyValues(GuidedAction)}. 43 */ 44public class GuidedAction extends Action { 45 46 private static final String TAG = "GuidedAction"; 47 48 /** 49 * Special check set Id that is neither checkbox nor radio. 50 */ 51 public static final int NO_CHECK_SET = 0; 52 /** 53 * Default checkset Id for radio. 54 */ 55 public static final int DEFAULT_CHECK_SET_ID = 1; 56 /** 57 * Checkset Id for checkbox. 58 */ 59 public static final int CHECKBOX_CHECK_SET_ID = -1; 60 61 /** 62 * When finishing editing, goes to next action. 63 */ 64 public static final long ACTION_ID_NEXT = -2; 65 /** 66 * When finishing editing, stay on current action. 67 */ 68 public static final long ACTION_ID_CURRENT = -3; 69 70 /** 71 * Id of standard OK action. 72 */ 73 public static final long ACTION_ID_OK = -4; 74 75 /** 76 * Id of standard Cancel action. 77 */ 78 public static final long ACTION_ID_CANCEL = -5; 79 80 /** 81 * Id of standard Finish action. 82 */ 83 public static final long ACTION_ID_FINISH = -6; 84 85 /** 86 * Id of standard Finish action. 87 */ 88 public static final long ACTION_ID_CONTINUE = -7; 89 90 /** 91 * Id of standard Yes action. 92 */ 93 public static final long ACTION_ID_YES = -8; 94 95 /** 96 * Id of standard No action. 97 */ 98 public static final long ACTION_ID_NO = -9; 99 100 /** 101 * Base builder class to build a {@link GuidedAction} object. When subclass GuidedAction, you 102 * can override this BuilderBase class, implements {@link #build()} and call 103 * {@link #applyValues(GuidedAction)}. When using GuidedAction directly, use {@link Builder}. 104 */ 105 public abstract static class BuilderBase<T extends GuidedAction> { 106 private Context mContext; 107 private long mId; 108 private CharSequence mTitle; 109 private CharSequence mEditTitle; 110 private CharSequence mDescription; 111 private CharSequence mEditDescription; 112 private Drawable mIcon; 113 private boolean mChecked; 114 private boolean mMultilineDescription; 115 private boolean mHasNext; 116 private boolean mInfoOnly; 117 private boolean mEditable = false; 118 private boolean mDescriptionEditable = false; 119 private int mInputType = InputType.TYPE_CLASS_TEXT; 120 private int mDescriptionInputType = InputType.TYPE_CLASS_TEXT; 121 private int mEditInputType = InputType.TYPE_CLASS_TEXT; 122 private int mDescriptionEditInputType = InputType.TYPE_CLASS_TEXT; 123 private int mCheckSetId = NO_CHECK_SET; 124 private boolean mEnabled = true; 125 private boolean mFocusable = true; 126 private List<GuidedAction> mSubActions; 127 private Intent mIntent; 128 129 /** 130 * Creates a BuilderBase for GuidedAction or its subclass. 131 * @param context Context object used to build the GuidedAction. 132 */ 133 public BuilderBase(Context context) { 134 mContext = context; 135 } 136 137 /** 138 * Returns Context of this Builder. 139 * @return Context of this Builder. 140 */ 141 public Context getContext() { 142 return mContext; 143 } 144 145 /** 146 * Builds the GuidedAction corresponding to this Builder. 147 * @return the GuidedAction as configured through this BuilderBase. 148 */ 149 public abstract T build(); 150 151 /** 152 * Subclass of BuilderBase should call this function to apply values. 153 * @param action GuidedAction to apply BuilderBase values. 154 */ 155 protected final void applyValues(GuidedAction action) { 156 // Base Action values 157 action.setId(mId); 158 action.setLabel1(mTitle); 159 action.setEditTitle(mEditTitle); 160 action.setLabel2(mDescription); 161 action.setEditDescription(mEditDescription); 162 action.setIcon(mIcon); 163 164 // Subclass values 165 action.mIntent = mIntent; 166 action.mEditable = mEditable; 167 action.mDescriptionEditable = mDescriptionEditable; 168 action.mInputType = mInputType; 169 action.mDescriptionInputType = mDescriptionInputType; 170 action.mEditInputType = mEditInputType; 171 action.mDescriptionEditInputType = mDescriptionEditInputType; 172 action.mChecked = mChecked; 173 action.mCheckSetId = mCheckSetId; 174 action.mMultilineDescription = mMultilineDescription; 175 action.mHasNext = mHasNext; 176 action.mInfoOnly = mInfoOnly; 177 action.mEnabled = mEnabled; 178 action.mFocusable = mFocusable; 179 action.mSubActions = mSubActions; 180 } 181 182 /** 183 * Construct a clickable action with associated id and auto assign pre-defined title for the 184 * action. If the id is not supported, the method simply does nothing. 185 * @param id One of {@link GuidedAction#ACTION_ID_OK} {@link GuidedAction#ACTION_ID_CANCEL} 186 * {@link GuidedAction#ACTION_ID_FINISH} {@link GuidedAction#ACTION_ID_CONTINUE} 187 * {@link GuidedAction#ACTION_ID_YES} {@link GuidedAction#ACTION_ID_NO}. 188 * @return The same BuilderBase object. 189 */ 190 public BuilderBase<T> clickAction(long id) { 191 if (id == ACTION_ID_OK) { 192 mId = ACTION_ID_OK; 193 mTitle = mContext.getString(android.R.string.ok); 194 } else if (id == ACTION_ID_CANCEL) { 195 mId = ACTION_ID_CANCEL; 196 mTitle = mContext.getString(android.R.string.cancel); 197 } else if (id == ACTION_ID_FINISH) { 198 mId = ACTION_ID_FINISH; 199 mTitle = mContext.getString(R.string.lb_guidedaction_finish_title); 200 } else if (id == ACTION_ID_CONTINUE) { 201 mId = ACTION_ID_CONTINUE; 202 mTitle = mContext.getString(R.string.lb_guidedaction_continue_title); 203 } else if (id == ACTION_ID_YES) { 204 mId = ACTION_ID_YES; 205 mTitle = mContext.getString(android.R.string.yes); 206 } else if (id == ACTION_ID_NO) { 207 mId = ACTION_ID_NO; 208 mTitle = mContext.getString(android.R.string.no); 209 } 210 return this; 211 } 212 213 /** 214 * Sets the ID associated with this action. The ID can be any value the client wishes; 215 * it is typically used to determine what to do when an action is clicked. 216 * @param id The ID to associate with this action. 217 */ 218 public BuilderBase<T> id(long id) { 219 mId = id; 220 return this; 221 } 222 223 /** 224 * Sets the title for this action. The title is typically a short string indicating the 225 * action to be taken on click, e.g. "Continue" or "Cancel". 226 * @param title The title for this action. 227 */ 228 public BuilderBase<T> title(CharSequence title) { 229 mTitle = title; 230 return this; 231 } 232 233 /** 234 * Sets the title for this action. The title is typically a short string indicating the 235 * action to be taken on click, e.g. "Continue" or "Cancel". 236 * @param titleResourceId The resource id of title for this action. 237 */ 238 public BuilderBase<T> title(@StringRes int titleResourceId) { 239 mTitle = getContext().getString(titleResourceId); 240 return this; 241 } 242 243 /** 244 * Sets the optional title text to edit. When TextView is activated, the edit title 245 * replaces the string of title. 246 * @param editTitle The optional title text to edit when TextView is activated. 247 */ 248 public BuilderBase<T> editTitle(CharSequence editTitle) { 249 mEditTitle = editTitle; 250 return this; 251 } 252 253 /** 254 * Sets the optional title text to edit. When TextView is activated, the edit title 255 * replaces the string of title. 256 * @param editTitleResourceId String resource id of the optional title text to edit when 257 * TextView is activated. 258 */ 259 public BuilderBase<T> editTitle(@StringRes int editTitleResourceId) { 260 mEditTitle = getContext().getString(editTitleResourceId); 261 return this; 262 } 263 264 /** 265 * Sets the description for this action. The description is typically a longer string 266 * providing extra information on what the action will do. 267 * @param description The description for this action. 268 */ 269 public BuilderBase<T> description(CharSequence description) { 270 mDescription = description; 271 return this; 272 } 273 274 /** 275 * Sets the description for this action. The description is typically a longer string 276 * providing extra information on what the action will do. 277 * @param descriptionResourceId String resource id of the description for this action. 278 */ 279 public BuilderBase<T> description(@StringRes int descriptionResourceId) { 280 mDescription = getContext().getString(descriptionResourceId); 281 return this; 282 } 283 284 /** 285 * Sets the optional description text to edit. When TextView is activated, the edit 286 * description replaces the string of description. 287 * @param description The description to edit for this action. 288 */ 289 public BuilderBase<T> editDescription(CharSequence description) { 290 mEditDescription = description; 291 return this; 292 } 293 294 /** 295 * Sets the optional description text to edit. When TextView is activated, the edit 296 * description replaces the string of description. 297 * @param descriptionResourceId String resource id of the description to edit for this 298 * action. 299 */ 300 public BuilderBase<T> editDescription(@StringRes int descriptionResourceId) { 301 mEditDescription = getContext().getString(descriptionResourceId); 302 return this; 303 } 304 305 /** 306 * Sets the intent associated with this action. Clients would typically fire this intent 307 * directly when the action is clicked. 308 * @param intent The intent associated with this action. 309 */ 310 public BuilderBase<T> intent(Intent intent) { 311 mIntent = intent; 312 return this; 313 } 314 315 /** 316 * Sets the action's icon drawable. 317 * @param icon The drawable for the icon associated with this action. 318 */ 319 public BuilderBase<T> icon(Drawable icon) { 320 mIcon = icon; 321 return this; 322 } 323 324 /** 325 * Sets the action's icon drawable by retrieving it by resource ID from the specified 326 * context. This is a convenience function that simply looks up the drawable and calls 327 * {@link #icon(Drawable)}. 328 * @param iconResourceId The resource ID for the icon associated with this action. 329 * @param context The context whose resource ID should be retrieved. 330 * @deprecated Use {@link #icon(int)}. 331 */ 332 @Deprecated 333 public BuilderBase<T> iconResourceId(@DrawableRes int iconResourceId, Context context) { 334 return icon(ContextCompat.getDrawable(context, iconResourceId)); 335 } 336 337 /** 338 * Sets the action's icon drawable by retrieving it by resource ID from Builder's 339 * context. This is a convenience function that simply looks up the drawable and calls 340 * {@link #icon(Drawable)}. 341 * @param iconResourceId The resource ID for the icon associated with this action. 342 */ 343 public BuilderBase<T> icon(@DrawableRes int iconResourceId) { 344 return icon(ContextCompat.getDrawable(getContext(), iconResourceId)); 345 } 346 347 /** 348 * Indicates whether this action title is editable. Note: Editable actions cannot also be 349 * checked, or belong to a check set. 350 * @param editable Whether this action is editable. 351 */ 352 public BuilderBase<T> editable(boolean editable) { 353 mEditable = editable; 354 if (mChecked || mCheckSetId != NO_CHECK_SET) { 355 throw new IllegalArgumentException("Editable actions cannot also be checked"); 356 } 357 return this; 358 } 359 360 /** 361 * Indicates whether this action's description is editable 362 * @param editable Whether this action description is editable. 363 */ 364 public BuilderBase<T> descriptionEditable(boolean editable) { 365 mDescriptionEditable = editable; 366 if (mChecked || mCheckSetId != NO_CHECK_SET) { 367 throw new IllegalArgumentException("Editable actions cannot also be checked"); 368 } 369 return this; 370 } 371 372 /** 373 * Sets {@link InputType} of this action title not in editing. 374 * 375 * @param inputType InputType for the action title not in editing. 376 */ 377 public BuilderBase<T> inputType(int inputType) { 378 mInputType = inputType; 379 return this; 380 } 381 382 /** 383 * Sets {@link InputType} of this action description not in editing. 384 * 385 * @param inputType InputType for the action description not in editing. 386 */ 387 public BuilderBase<T> descriptionInputType(int inputType) { 388 mDescriptionInputType = inputType; 389 return this; 390 } 391 392 393 /** 394 * Sets {@link InputType} of this action title in editing. 395 * 396 * @param inputType InputType for the action title in editing. 397 */ 398 public BuilderBase<T> editInputType(int inputType) { 399 mEditInputType = inputType; 400 return this; 401 } 402 403 /** 404 * Sets {@link InputType} of this action description in editing. 405 * 406 * @param inputType InputType for the action description in editing. 407 */ 408 public BuilderBase<T> descriptionEditInputType(int inputType) { 409 mDescriptionEditInputType = inputType; 410 return this; 411 } 412 413 414 /** 415 * Indicates whether this action is initially checked. 416 * @param checked Whether this action is checked. 417 */ 418 public BuilderBase<T> checked(boolean checked) { 419 mChecked = checked; 420 if (mEditable || mDescriptionEditable) { 421 throw new IllegalArgumentException("Editable actions cannot also be checked"); 422 } 423 return this; 424 } 425 426 /** 427 * Indicates whether this action is part of a single-select group similar to radio buttons 428 * or this action is a checkbox. When one item in a check set is checked, all others with 429 * the same check set ID will be checked automatically. 430 * @param checkSetId The check set ID, or {@link GuidedAction#NO_CHECK_SET} to indicate not 431 * radio or checkbox, or {@link GuidedAction#CHECKBOX_CHECK_SET_ID} to indicate a checkbox. 432 */ 433 public BuilderBase<T> checkSetId(int checkSetId) { 434 mCheckSetId = checkSetId; 435 if (mEditable || mDescriptionEditable) { 436 throw new IllegalArgumentException("Editable actions cannot also be in check sets"); 437 } 438 return this; 439 } 440 441 /** 442 * Indicates whether the title and description are long, and should be displayed 443 * appropriately. 444 * @param multilineDescription Whether this action has a multiline description. 445 */ 446 public BuilderBase<T> multilineDescription(boolean multilineDescription) { 447 mMultilineDescription = multilineDescription; 448 return this; 449 } 450 451 /** 452 * Indicates whether this action has a next state and should display a chevron. 453 * @param hasNext Whether this action has a next state. 454 */ 455 public BuilderBase<T> hasNext(boolean hasNext) { 456 mHasNext = hasNext; 457 return this; 458 } 459 460 /** 461 * Indicates whether this action is for information purposes only and cannot be clicked. 462 * @param infoOnly Whether this action has a next state. 463 */ 464 public BuilderBase<T> infoOnly(boolean infoOnly) { 465 mInfoOnly = infoOnly; 466 return this; 467 } 468 469 /** 470 * Indicates whether this action is enabled. If not enabled, an action cannot be clicked. 471 * @param enabled Whether the action is enabled. 472 */ 473 public BuilderBase<T> enabled(boolean enabled) { 474 mEnabled = enabled; 475 return this; 476 } 477 478 /** 479 * Indicates whether this action can take focus. 480 * @param focusable 481 * @return The same BuilderBase object. 482 */ 483 public BuilderBase<T> focusable(boolean focusable) { 484 mFocusable = focusable; 485 return this; 486 } 487 488 /** 489 * Sets sub actions list. 490 * @param subActions 491 * @return The same BuilderBase object. 492 */ 493 public BuilderBase<T> subActions(List<GuidedAction> subActions) { 494 mSubActions = subActions; 495 return this; 496 } 497 } 498 499 /** 500 * Builds a {@link GuidedAction} object. 501 */ 502 public static class Builder extends BuilderBase<GuidedAction> { 503 504 /** 505 * @deprecated Use {@link GuidedAction.Builder#GuidedAction.Builder(Context)}. 506 */ 507 @Deprecated 508 public Builder() { 509 super(null); 510 } 511 512 /** 513 * Creates a Builder for GuidedAction. 514 * @param context Context to build GuidedAction. 515 */ 516 public Builder(Context context) { 517 super(context); 518 } 519 520 @Override 521 public GuidedAction build() { 522 GuidedAction action = new GuidedAction(); 523 applyValues(action); 524 return action; 525 } 526 527 } 528 529 private CharSequence mEditTitle; 530 private CharSequence mEditDescription; 531 private boolean mEditable; 532 private boolean mDescriptionEditable; 533 private int mInputType; 534 private int mDescriptionInputType; 535 private int mEditInputType; 536 private int mDescriptionEditInputType; 537 private boolean mMultilineDescription; 538 private boolean mHasNext; 539 private boolean mChecked; 540 private boolean mInfoOnly; 541 private int mCheckSetId; 542 private boolean mEnabled; 543 private boolean mFocusable; 544 private List<GuidedAction> mSubActions; 545 546 private Intent mIntent; 547 548 protected GuidedAction() { 549 super(0); 550 } 551 552 /** 553 * Returns the title of this action. 554 * @return The title set when this action was built. 555 */ 556 public CharSequence getTitle() { 557 return getLabel1(); 558 } 559 560 /** 561 * Sets the title of this action. 562 * @param title The title set when this action was built. 563 */ 564 public void setTitle(CharSequence title) { 565 setLabel1(title); 566 } 567 568 /** 569 * Returns the optional title text to edit. When not null, it is being edited instead of 570 * {@link #getTitle()}. 571 * @return Optional title text to edit instead of {@link #getTitle()}. 572 */ 573 public CharSequence getEditTitle() { 574 return mEditTitle; 575 } 576 577 /** 578 * Sets the optional title text to edit instead of {@link #setTitle(CharSequence)}. 579 * @param editTitle Optional title text to edit instead of {@link #setTitle(CharSequence)}. 580 */ 581 public void setEditTitle(CharSequence editTitle) { 582 mEditTitle = editTitle; 583 } 584 585 /** 586 * Returns the optional description text to edit. When not null, it is being edited instead of 587 * {@link #getDescription()}. 588 * @return Optional description text to edit instead of {@link #getDescription()}. 589 */ 590 public CharSequence getEditDescription() { 591 return mEditDescription; 592 } 593 594 /** 595 * Sets the optional description text to edit instead of {@link #setDescription(CharSequence)}. 596 * @param editDescription Optional description text to edit instead of 597 * {@link #setDescription(CharSequence)}. 598 */ 599 public void setEditDescription(CharSequence editDescription) { 600 mEditDescription = editDescription; 601 } 602 603 /** 604 * Returns true if {@link #getEditTitle()} is not null. When true, the {@link #getEditTitle()} 605 * is being edited instead of {@link #getTitle()}. 606 * @return true if {@link #getEditTitle()} is not null. 607 */ 608 public boolean isEditTitleUsed() { 609 return mEditTitle != null; 610 } 611 612 /** 613 * Returns the description of this action. 614 * @return The description of this action. 615 */ 616 public CharSequence getDescription() { 617 return getLabel2(); 618 } 619 620 /** 621 * Sets the description of this action. 622 * @param description The description of the action. 623 */ 624 public void setDescription(CharSequence description) { 625 setLabel2(description); 626 } 627 628 /** 629 * Returns the intent associated with this action. 630 * @return The intent set when this action was built. 631 */ 632 public Intent getIntent() { 633 return mIntent; 634 } 635 636 /** 637 * Sets the intent of this action. 638 * @param intent New intent to set on this action. 639 */ 640 public void setIntent(Intent intent) { 641 mIntent = intent; 642 } 643 644 /** 645 * Returns whether this action title is editable. 646 * @return true if the action title is editable, false otherwise. 647 */ 648 public boolean isEditable() { 649 return mEditable; 650 } 651 652 /** 653 * Returns whether this action description is editable. 654 * @return true if the action description is editable, false otherwise. 655 */ 656 public boolean isDescriptionEditable() { 657 return mDescriptionEditable; 658 } 659 660 /** 661 * Returns InputType of action title in editing; only valid when {@link #isEditable()} is true. 662 * @return InputType of action title in editing. 663 */ 664 public int getEditInputType() { 665 return mEditInputType; 666 } 667 668 /** 669 * Returns InputType of action description in editing; only valid when 670 * {@link #isDescriptionEditable()} is true. 671 * @return InputType of action description in editing. 672 */ 673 public int getDescriptionEditInputType() { 674 return mDescriptionEditInputType; 675 } 676 677 /** 678 * Returns InputType of action title not in editing. 679 * @return InputType of action title not in editing. 680 */ 681 public int getInputType() { 682 return mInputType; 683 } 684 685 /** 686 * Returns InputType of action description not in editing. 687 * @return InputType of action description not in editing. 688 */ 689 public int getDescriptionInputType() { 690 return mDescriptionInputType; 691 } 692 693 /** 694 * Returns whether this action is checked. 695 * @return true if the action is currently checked, false otherwise. 696 */ 697 public boolean isChecked() { 698 return mChecked; 699 } 700 701 /** 702 * Sets whether this action is checked. 703 * @param checked Whether this action should be checked. 704 */ 705 public void setChecked(boolean checked) { 706 mChecked = checked; 707 } 708 709 /** 710 * Returns the check set id this action is a part of. All actions in the same list with the same 711 * check set id are considered linked. When one of the actions within that set is selected, that 712 * action becomes checked, while all the other actions become unchecked. 713 * 714 * @return an integer representing the check set this action is a part of, or 715 * {@link #CHECKBOX_CHECK_SET_ID} if this is a checkbox, or {@link #NO_CHECK_SET} if 716 * this action is not a checkbox or radiobutton. 717 */ 718 public int getCheckSetId() { 719 return mCheckSetId; 720 } 721 722 /** 723 * Returns whether this action is has a multiline description. 724 * @return true if the action was constructed as having a multiline description, false 725 * otherwise. 726 */ 727 public boolean hasMultilineDescription() { 728 return mMultilineDescription; 729 } 730 731 /** 732 * Returns whether this action is enabled. 733 * @return true if the action is currently enabled, false otherwise. 734 */ 735 public boolean isEnabled() { 736 return mEnabled; 737 } 738 739 /** 740 * Sets whether this action is enabled. 741 * @param enabled Whether this action should be enabled. 742 */ 743 public void setEnabled(boolean enabled) { 744 mEnabled = enabled; 745 } 746 747 /** 748 * Returns whether this action is focusable. 749 * @return true if the action is currently focusable, false otherwise. 750 */ 751 public boolean isFocusable() { 752 return mFocusable; 753 } 754 755 /** 756 * Sets whether this action is focusable. 757 * @param focusable Whether this action should be focusable. 758 */ 759 public void setFocusable(boolean focusable) { 760 mFocusable = focusable; 761 } 762 763 /** 764 * Returns whether this action will request further user input when selected, such as showing 765 * another GuidedStepFragment or launching a new activity. Configured during construction. 766 * @return true if the action will request further user input when selected, false otherwise. 767 */ 768 public boolean hasNext() { 769 return mHasNext; 770 } 771 772 /** 773 * Returns whether the action will only display information and is thus not clickable. If both 774 * this and {@link #hasNext()} are true, infoOnly takes precedence. The default is false. For 775 * example, this might represent e.g. the amount of storage a document uses, or the cost of an 776 * app. 777 * @return true if will only display information, false otherwise. 778 */ 779 public boolean infoOnly() { 780 return mInfoOnly; 781 } 782 783 /** 784 * Change sub actions list. 785 * @param actions Sub actions list to set on this action. Sets null to disable sub actions. 786 */ 787 public void setSubActions(List<GuidedAction> actions) { 788 mSubActions = actions; 789 } 790 791 /** 792 * @return List of sub actions or null if sub actions list is not enabled. 793 */ 794 public List<GuidedAction> getSubActions() { 795 return mSubActions; 796 } 797 798 /** 799 * @return True if has sub actions list, even it's currently empty. 800 */ 801 public boolean hasSubActions() { 802 return mSubActions != null; 803 } 804 805} 806