1 /* 2 * Copyright (C) 2019 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.android.tv.twopanelsettings.slices.builders; 18 19 import static com.android.tv.twopanelsettings.slices.SlicesConstants.BUTTONSTYLE; 20 import static com.android.tv.twopanelsettings.slices.SlicesConstants.CHECKMARK; 21 import static com.android.tv.twopanelsettings.slices.SlicesConstants.RADIO; 22 import static com.android.tv.twopanelsettings.slices.SlicesConstants.SWITCH; 23 24 import android.app.PendingIntent; 25 import android.content.Context; 26 import android.net.Uri; 27 import android.view.View; 28 29 import androidx.annotation.IntDef; 30 import androidx.annotation.NonNull; 31 import androidx.annotation.Nullable; 32 import androidx.annotation.RestrictTo; 33 import androidx.core.graphics.drawable.IconCompat; 34 import androidx.core.util.Pair; 35 import androidx.slice.Slice; 36 import androidx.slice.SliceSpecs; 37 import androidx.slice.builders.ListBuilder; 38 import androidx.slice.builders.SliceAction; 39 import androidx.slice.core.SliceHints; 40 41 import java.lang.annotation.Retention; 42 import java.lang.annotation.RetentionPolicy; 43 import java.time.Duration; 44 import java.util.ArrayList; 45 import java.util.List; 46 47 // TODO: Remove unused code and add test. 48 /** 49 * Builder for constructing slices composed of rows of TvSettings style preferences. 50 */ 51 public class PreferenceSliceBuilder extends TemplateSliceBuilder { 52 53 private PreferenceSliceBuilderImpl mImpl; 54 55 /** 56 * Constant representing infinity. 57 */ 58 public static final long INFINITY = SliceHints.INFINITY; 59 60 /** 61 * @hide 62 */ 63 @RestrictTo(RestrictTo.Scope.LIBRARY) 64 @IntDef({ 65 View.LAYOUT_DIRECTION_RTL, View.LAYOUT_DIRECTION_LTR, View.LAYOUT_DIRECTION_INHERIT, 66 View.LAYOUT_DIRECTION_LOCALE 67 }) 68 @Retention(RetentionPolicy.SOURCE) 69 public @interface LayoutDirection { 70 71 } 72 73 /** 74 * Create a builder which will construct a slice made up of rows of content. 75 * 76 * @param uri Uri to tag for this slice. 77 * @hide 78 */ PreferenceSliceBuilder(@onNull Context context, @NonNull Uri uri)79 public PreferenceSliceBuilder(@NonNull Context context, @NonNull Uri uri) { 80 super(context, uri); 81 } 82 83 /** 84 * Create a ListBuilder for constructing slice content. 85 * <p> 86 * A slice requires an associated time-to-live, i.e. how long the data contained in the slice 87 * can remain fresh. If your slice has content that is not time sensitive, set a TTL of {@link 88 * #INFINITY}. 89 * 90 * @param uri Uri to tag for this slice. 91 * @param ttl the length in milliseconds that the content in this slice can live for. 92 */ PreferenceSliceBuilder(@onNull Context context, @NonNull Uri uri, long ttl)93 public PreferenceSliceBuilder(@NonNull Context context, @NonNull Uri uri, long ttl) { 94 super(context, uri); 95 mImpl.setTtl(ttl); 96 } 97 98 /** 99 * Create a ListBuilder for constructing slice content. 100 * <p> 101 * A slice requires an associated time-to-live, i.e. how long the data contained in the slice 102 * can remain fresh. If your slice has content that is not time sensitive, set {@link Duration} 103 * to null and the TTL will be {@link #INFINITY}. 104 * 105 * @param uri Uri to tag for this slice. 106 * @param ttl the {@link Duration} that the content in this slice can live for. 107 */ PreferenceSliceBuilder(@onNull Context context, @NonNull Uri uri, @Nullable Duration ttl)108 public PreferenceSliceBuilder(@NonNull Context context, @NonNull Uri uri, 109 @Nullable Duration ttl) { 110 super(context, uri); 111 mImpl.setTtl(ttl); 112 } 113 114 @Override selectImpl(Uri uri)115 protected TemplateBuilderImpl selectImpl(Uri uri) { 116 return new PreferenceSliceBuilderImpl(getBuilder(), SliceSpecs.LIST, getClock()); 117 } 118 119 /** 120 * Construct the slice defined by this PreferenceSliceBuilder 121 */ 122 @NonNull 123 @Override build()124 public Slice build() { 125 return mImpl.build(); 126 } 127 128 @Override setImpl(TemplateBuilderImpl impl)129 void setImpl(TemplateBuilderImpl impl) { 130 mImpl = (PreferenceSliceBuilderImpl) impl; 131 } 132 133 /** 134 * Add a preference builder. If the row is expected to be actionable, it is recommended to 135 * invoke setActionId() for the RowBuilder to help with logging. 136 */ addPreference(RowBuilder builder)137 public PreferenceSliceBuilder addPreference(RowBuilder builder) { 138 mImpl.addPreference(builder); 139 return this; 140 } 141 142 /** 143 * Add a preferenceCategory builder. 144 */ addPreferenceCategory(RowBuilder builder)145 public PreferenceSliceBuilder addPreferenceCategory(RowBuilder builder) { 146 mImpl.addPreferenceCategory(builder); 147 return this; 148 } 149 150 /** 151 * Set a custom screen title for slice. It is recommended to invoke setPageId() for the 152 * RowBuilder in addition to setTitle(), to help with logging. 153 */ addScreenTitle(RowBuilder builder)154 public PreferenceSliceBuilder addScreenTitle(RowBuilder builder) { 155 mImpl.addScreenTitle(builder); 156 return this; 157 } 158 159 /** 160 * Set the focused preference for slice. 161 * @param key key of the focused preference. 162 */ setFocusedPreference(CharSequence key)163 public PreferenceSliceBuilder setFocusedPreference(CharSequence key) { 164 mImpl.setFocusedPreference(key); 165 return this; 166 } 167 168 /** Add a preference which can be embedded in other settings items. **/ setEmbeddedPreference(RowBuilder builder)169 public PreferenceSliceBuilder setEmbeddedPreference(RowBuilder builder) { 170 mImpl.setEmbeddedPreference(builder); 171 return this; 172 } 173 174 /** Indicates that the slice is not ready yet **/ setNotReady()175 public PreferenceSliceBuilder setNotReady() { 176 mImpl.setNotReady(); 177 return this; 178 } 179 180 public static class RowBuilder { 181 182 private final Uri mUri; 183 private boolean mHasEndActionOrToggle; 184 private boolean mHasEndImage; 185 private boolean mHasDefaultToggle; 186 private boolean mTitleItemLoading; 187 private IconCompat mTitleIcon; 188 private SliceAction mTitleAction; 189 private SliceAction mPrimaryAction; 190 private SliceAction mFollowupAction; 191 private int mActionId; 192 private int mPageId; 193 private CharSequence mTitle; 194 private boolean mTitleLoading; 195 private CharSequence mSubtitle; 196 private boolean mSubtitleLoading; 197 private CharSequence mContentDescription; 198 private CharSequence mInfoText; 199 private IconCompat mInfoImage; 200 private int mLayoutDirection = -1; 201 private List<Object> mEndItems = new ArrayList<>(); 202 private List<Integer> mEndTypes = new ArrayList<>(); 203 private List<Boolean> mEndLoads = new ArrayList<>(); 204 private List<Pair<String, String>> mInfoItems = new ArrayList<>(); 205 private boolean mTitleActionLoading; 206 private CharSequence mTargetSliceUri; 207 private CharSequence mKey; 208 private boolean mIconNeedsToBeProcessed; 209 private @BUTTONSTYLE int mButtonStyle; 210 private CharSequence mRadioGroup; 211 private boolean mEnabled; 212 private boolean mSelectable; 213 214 public static final int TYPE_ICON = 1; 215 public static final int TYPE_ACTION = 2; 216 217 /** 218 * Builder to construct a row. 219 */ RowBuilder()220 public RowBuilder() { 221 mEnabled = true; 222 mSelectable = true; 223 mUri = null; 224 } 225 226 /** 227 * Builder to construct a normal row. 228 * 229 * @param uri Uri to tag for this slice. 230 */ RowBuilder(Uri uri)231 public RowBuilder(Uri uri) { 232 mEnabled = true; 233 mSelectable = true; 234 mUri = uri; 235 } 236 237 /** 238 * Builder to construct a row. 239 * 240 * @param parent The builder constructing the parent slice. 241 */ RowBuilder(@onNull ListBuilder parent)242 public RowBuilder(@NonNull ListBuilder parent) { 243 this(); 244 } 245 246 /** 247 * Builder to construct a row. 248 * 249 * @param uri Uri to tag for this slice. 250 */ RowBuilder(@onNull ListBuilder parent, @NonNull Uri uri)251 public RowBuilder(@NonNull ListBuilder parent, @NonNull Uri uri) { 252 this(uri); 253 } 254 255 /** 256 * Builder to construct a normal row. 257 * 258 * @param uri Uri to tag for this slice. 259 */ RowBuilder(@onNull Context context, @NonNull Uri uri)260 public RowBuilder(@NonNull Context context, @NonNull Uri uri) { 261 this(uri); 262 } 263 264 /** 265 * Sets the title item to be the provided icon. There can only be one title item, this will 266 * replace any other title items that may have been set. 267 * 268 * @param icon the image to display. 269 */ setTitleItem(@onNull IconCompat icon)270 private RowBuilder setTitleItem(@NonNull IconCompat icon) { 271 return setTitleItem(icon, false /* isLoading */); 272 } 273 274 /** 275 * Sets the title item to be the provided icon. There can only be one title item, this will 276 * replace any other title items that may have been set. 277 * <p> 278 * When set to true, the parameter {@code isLoading} indicates that the app is doing work to 279 * load this content in the background, in this case the template displays a placeholder 280 * until updated. 281 * 282 * @param icon the image to display. 283 * @param isLoading whether this content is being loaded in the background. 284 */ 285 @NonNull setTitleItem(@ullable IconCompat icon, boolean isLoading)286 private RowBuilder setTitleItem(@Nullable IconCompat icon, boolean isLoading) { 287 mTitleAction = null; 288 mTitleIcon = icon; 289 mTitleItemLoading = isLoading; 290 return this; 291 } 292 293 /** 294 * Sets the title item to be a tappable icon. There can only be one title item, this will 295 * replace any other title items that may have been set. 296 */ 297 @NonNull setTitleItem(@onNull SliceAction action)298 private RowBuilder setTitleItem(@NonNull SliceAction action) { 299 return setTitleItem(action, false /* isLoading */); 300 } 301 302 /** 303 * Sets the title item to be a tappable icon. There can only be one title item, this will 304 * replace any other title items that may have been set. 305 * <p> 306 * Use this method to specify content that will appear in the template once it's been 307 * loaded. 308 * </p> 309 * 310 * @param isLoading indicates whether the app is doing work to load the added content in the 311 * background or not. 312 */ 313 @NonNull setTitleItem(@onNull SliceAction action, boolean isLoading)314 private RowBuilder setTitleItem(@NonNull SliceAction action, boolean isLoading) { 315 mTitleAction = action; 316 mTitleIcon = null; 317 mTitleActionLoading = isLoading; 318 return this; 319 } 320 321 /** 322 * Sets the icon for the preference builder. 323 */ 324 @NonNull setIcon(@onNull IconCompat icon)325 public RowBuilder setIcon(@NonNull IconCompat icon) { 326 return setTitleItem(icon); 327 } 328 329 /** 330 * Sets the information image for the preference builder. 331 * The image would be displayed at the top of preview screen. 332 */ 333 @NonNull setInfoImage(@onNull IconCompat icon)334 public RowBuilder setInfoImage(@NonNull IconCompat icon) { 335 mInfoImage = icon; 336 return this; 337 } 338 339 /** 340 * Sets the information text for the preference builder. 341 * The image would be displayed at the top of preview screen. 342 */ 343 @NonNull setInfoText(CharSequence text)344 public RowBuilder setInfoText(CharSequence text) { 345 mInfoText = text; 346 return this; 347 } 348 349 /** 350 * The action specified here will be sent when the whole row is clicked. 351 * <p> 352 * If this is the first row in a {@link ListBuilder} this action will also be used to define 353 * the {@link androidx.slice.widget.SliceView#MODE_SHORTCUT} representation of the slice. 354 */ 355 @NonNull setPrimaryAction(@onNull SliceAction action)356 private RowBuilder setPrimaryAction(@NonNull SliceAction action) { 357 mPrimaryAction = action; 358 return this; 359 } 360 361 /** 362 * Set a pendingIntent for the preference builder. 363 * @param pendingIntent pendingIntent 364 * @return builder 365 */ 366 @NonNull setPendingIntent(@onNull PendingIntent pendingIntent)367 public RowBuilder setPendingIntent(@NonNull PendingIntent pendingIntent) { 368 return setPrimaryAction(new SliceAction(pendingIntent, "", false)); 369 } 370 371 /** 372 * Set a followup pendingIntent for the preference builder. After the initial pendingIntent 373 * is launched and result is retrieved by TvSettings, TvSettings will pack the result into 374 * the followup PendingIntent and launch it. 375 * @param pendingIntent followup pendingIntent 376 * @return builder 377 */ 378 @NonNull setFollowupPendingIntent(@onNull PendingIntent pendingIntent)379 public RowBuilder setFollowupPendingIntent(@NonNull PendingIntent pendingIntent) { 380 mFollowupAction = new SliceAction(pendingIntent, "", false); 381 return this; 382 } 383 384 /** 385 * Set the action ID for the row builder. If this is invoked for building an actionable row, 386 * it will be digested as actionId for logging purpose when the action is triggered. 387 * 388 * @param actionId pre-defined ID of an action 389 */ 390 @NonNull setActionId(int actionId)391 public RowBuilder setActionId(int actionId) { 392 mActionId = actionId; 393 return this; 394 } 395 396 /** 397 * Set the page ID for the row builder. If this is invoked for building the screen title 398 * row, it will be digested as pageId for logging purpose when the SliceFragment is focused. 399 * 400 * @param pageId pre-defined ID of a page 401 */ 402 @NonNull setPageId(int pageId)403 public RowBuilder setPageId(int pageId) { 404 mPageId = pageId; 405 return this; 406 } 407 408 /** 409 * Sets the title for the row builder. A title should fit on a single line and is ellipsized 410 * if too long. 411 */ 412 @NonNull setTitle(@onNull CharSequence title)413 public RowBuilder setTitle(@NonNull CharSequence title) { 414 return setTitle(title, false); 415 } 416 417 /** 418 * Sets the title for the row builder. A title should fit on a single line and is ellipsized 419 * if too long. 420 * <p> 421 * Use this method to specify content that will appear in the template once it's been 422 * loaded. 423 * </p> 424 * 425 * @param isLoading indicates whether the app is doing work to load the added content in the 426 * background or not. 427 */ 428 @NonNull setTitle(@ullable CharSequence title, boolean isLoading)429 public RowBuilder setTitle(@Nullable CharSequence title, boolean isLoading) { 430 mTitle = title; 431 mTitleLoading = isLoading; 432 return this; 433 } 434 435 /** 436 * Sets the subtitle for the row builder. A subtitle should fit on a single line and is 437 * ellipsized if too long. 438 */ 439 @NonNull setSubtitle(@onNull CharSequence subtitle)440 public RowBuilder setSubtitle(@NonNull CharSequence subtitle) { 441 return setSubtitle(subtitle, false /* isLoading */); 442 } 443 444 /** 445 * Sets the subtitle for the row builder. A subtitle should fit on a single line and is 446 * ellipsized if too long. 447 * <p> 448 * Use this method to specify content that will appear in the template once it's been 449 * loaded. 450 * </p> 451 * 452 * @param isLoading indicates whether the app is doing work to load the added content in the 453 * background or not. 454 */ 455 @NonNull setSubtitle(@ullable CharSequence subtitle, boolean isLoading)456 public RowBuilder setSubtitle(@Nullable CharSequence subtitle, boolean isLoading) { 457 mSubtitle = subtitle; 458 mSubtitleLoading = isLoading; 459 return this; 460 } 461 462 /** 463 * Adds an icon to the end items of the row builder. 464 * 465 * @param icon the image to display. 466 */ 467 @NonNull addEndItem(@onNull IconCompat icon)468 private RowBuilder addEndItem(@NonNull IconCompat icon) { 469 return addEndItem(icon, false /* isLoading */); 470 } 471 472 /** 473 * Adds an icon to the end items of the row builder. 474 * <p> 475 * When set to true, the parameter {@code isLoading} indicates that the app is doing work to 476 * load this content in the background, in this case the template displays a placeholder 477 * until updated. 478 * 479 * @param icon the image to display. 480 * @param isLoading whether this content is being loaded in the background. 481 */ 482 @NonNull addEndItem(@ullable IconCompat icon, boolean isLoading)483 private RowBuilder addEndItem(@Nullable IconCompat icon, boolean isLoading) { 484 if (mHasEndActionOrToggle) { 485 throw new IllegalArgumentException("Trying to add an icon to end items when an" 486 + "action has already been added. End items cannot have a mixture of " 487 + "actions and icons."); 488 } 489 mEndItems.add(new Pair<>(icon, 0)); 490 mEndTypes.add(TYPE_ICON); 491 mEndLoads.add(isLoading); 492 mHasEndImage = true; 493 return this; 494 } 495 496 /** 497 * Adds an action to the end items of the row builder. A mixture of icons and actions is not 498 * permitted. If an icon has already been added, this will throw {@link 499 * IllegalArgumentException}. 500 */ 501 @NonNull addEndItem(@onNull SliceAction action)502 private RowBuilder addEndItem(@NonNull SliceAction action) { 503 return addEndItem(action, false /* isLoading */); 504 } 505 506 507 /** 508 * Add an item to the RowBuilder. Each item would contain title and summary. 509 */ addInfoItem(String title, String summary)510 public RowBuilder addInfoItem(String title, String summary) { 511 mInfoItems.add(new Pair<>(title, summary)); 512 return this; 513 } 514 515 /** 516 * Add a radio button to the RowBuilder. 517 * @param pendingIntent pendingIntent to launch when radio is clicked. 518 * @param isChecked Initial state of the radio button 519 */ addRadioButton( PendingIntent pendingIntent, boolean isChecked)520 public RowBuilder addRadioButton( 521 PendingIntent pendingIntent, boolean isChecked) { 522 return addButton(pendingIntent, isChecked, RADIO); 523 } 524 525 /** 526 * Add a radio button to the RowBuilder. 527 * @param pendingIntent pendingIntent to launch when radio is clicked. 528 * @param isChecked Initial state of the radio button 529 * @param radioGroup group of the radio 530 */ addRadioButton( PendingIntent pendingIntent, boolean isChecked, CharSequence radioGroup)531 public RowBuilder addRadioButton( 532 PendingIntent pendingIntent, boolean isChecked, CharSequence radioGroup) { 533 return addButton(pendingIntent, isChecked, RADIO).setRadioGroup(radioGroup); 534 } 535 536 /** 537 * Add a checkmark to the RowBuilder. 538 * @param pendingIntent pendingIntent to launch when checkmark is clicked. 539 * @param isChecked Initial state of the check mark. 540 */ addCheckMark( PendingIntent pendingIntent, boolean isChecked)541 public RowBuilder addCheckMark( 542 PendingIntent pendingIntent, boolean isChecked) { 543 return addButton(pendingIntent, isChecked, CHECKMARK); 544 } 545 546 /** 547 * Add a switch to the RowBuilder. 548 * @param pendingIntent pendingIntent to launch when switch is clicked. 549 * @param isChecked Initial state of the switch. 550 */ addSwitch( PendingIntent pendingIntent, boolean isChecked)551 public RowBuilder addSwitch( 552 PendingIntent pendingIntent, boolean isChecked) { 553 return addButton(pendingIntent, isChecked, SWITCH); 554 } 555 addButton( PendingIntent pendingIntent, boolean isChecked, @BUTTONSTYLE int style)556 private RowBuilder addButton( 557 PendingIntent pendingIntent, boolean isChecked, @BUTTONSTYLE int style) { 558 SliceAction switchAction = new SliceAction(pendingIntent, "", isChecked); 559 mButtonStyle = style; 560 return addEndItem(switchAction); 561 } 562 563 /** 564 * Add a switch for the preference. 565 * @param pendingIntent pendingIntent 566 * @param actionTitle title for the switch, also used for contentDescription. 567 * @param isChecked the state of the switch 568 * @return 569 */ 570 @NonNull addSwitch( PendingIntent pendingIntent, @NonNull CharSequence actionTitle, boolean isChecked)571 public PreferenceSliceBuilder.RowBuilder addSwitch( 572 PendingIntent pendingIntent, @NonNull CharSequence actionTitle, boolean isChecked) { 573 SliceAction switchAction = new SliceAction(pendingIntent, actionTitle, isChecked); 574 mButtonStyle = SWITCH; 575 return addEndItem(switchAction); 576 } 577 578 /** 579 * Adds an action to the end items of the row builder. A mixture of icons and actions is not 580 * permitted. If an icon has already been added, this will throw {@link 581 * IllegalArgumentException}. 582 * <p> 583 * Use this method to specify content that will appear in the template once it's been 584 * loaded. 585 * </p> 586 * 587 * @param isLoading indicates whether the app is doing work to load the added content in the 588 * background or not. 589 */ 590 @NonNull addEndItem(@onNull SliceAction action, boolean isLoading)591 private RowBuilder addEndItem(@NonNull SliceAction action, boolean isLoading) { 592 if (mHasEndImage) { 593 throw new IllegalArgumentException("Trying to add an action to end items when an" 594 + "icon has already been added. End items cannot have a mixture of " 595 + "actions and icons."); 596 } 597 if (mHasDefaultToggle) { 598 throw new IllegalStateException("Only one non-custom toggle can be added " 599 + "in a single row. If you would like to include multiple toggles " 600 + "in a row, set a custom icon for each toggle."); 601 } 602 mEndItems.add(action); 603 mEndTypes.add(TYPE_ACTION); 604 mEndLoads.add(isLoading); 605 mHasDefaultToggle = action.getImpl().isDefaultToggle(); 606 mHasEndActionOrToggle = true; 607 return this; 608 } 609 610 /** 611 * Sets the content description for the row. 612 */ 613 @NonNull setContentDescription(@onNull CharSequence description)614 public RowBuilder setContentDescription(@NonNull CharSequence description) { 615 mContentDescription = description; 616 return this; 617 } 618 619 /** 620 * Set the target slice uri for the builder. 621 * @param targetSliceUri indicates the target slice uri when the preference is focused. 622 * @return builder 623 */ setTargetSliceUri(@onNull CharSequence targetSliceUri)624 public RowBuilder setTargetSliceUri(@NonNull CharSequence targetSliceUri) { 625 mTargetSliceUri = targetSliceUri; 626 return this; 627 } 628 629 /** 630 * Set the key for the builder. 631 * @param key indicates the key for the preference. 632 * @return builder 633 */ setKey(@onNull CharSequence key)634 public RowBuilder setKey(@NonNull CharSequence key) { 635 mKey = key; 636 return this; 637 } 638 639 /** 640 * Sets the desired layout direction for the content in this row. 641 * 642 * @param layoutDirection the layout direction to set. 643 */ 644 @NonNull setLayoutDirection(@ayoutDirection int layoutDirection)645 public RowBuilder setLayoutDirection(@LayoutDirection int layoutDirection) { 646 mLayoutDirection = layoutDirection; 647 return this; 648 } 649 650 /** 651 * Set whether the toggle use a checkmark style. Otherwise, a switch style is used. 652 * @param isCheckMark use checkmark. 653 * @deprecated use {@link PreferenceSliceBuilder.RowBuilder#setButtonStyle(int)} 654 */ 655 @Deprecated 656 @NonNull setCheckmark(boolean isCheckMark)657 public RowBuilder setCheckmark(boolean isCheckMark) { 658 if (isCheckMark) { 659 mButtonStyle = CHECKMARK; 660 } else { 661 mButtonStyle = SWITCH; 662 } 663 return this; 664 } 665 666 /** 667 * Set the button style. 668 * @param buttonStyle 669 */ setButtonStyle(@UTTONSTYLE int buttonStyle)670 public RowBuilder setButtonStyle(@BUTTONSTYLE int buttonStyle) { 671 mButtonStyle = buttonStyle; 672 return this; 673 } 674 675 /** 676 * Set whether the icon needs to be processed by TvSettings. 677 * @param needed if true, TvSettings will add a round border around the given icon 678 */ 679 @NonNull setIconNeedsToBeProcessed(boolean needed)680 public RowBuilder setIconNeedsToBeProcessed(boolean needed) { 681 mIconNeedsToBeProcessed = needed; 682 return this; 683 } 684 685 /** 686 * Set radio group for radio 687 */ 688 @NonNull setRadioGroup(CharSequence radioGroup)689 public RowBuilder setRadioGroup(CharSequence radioGroup) { 690 mRadioGroup = radioGroup; 691 return this; 692 } 693 694 /** 695 * Set whether this item is enabled. 696 */ 697 @NonNull setEnabled(boolean enabled)698 public RowBuilder setEnabled(boolean enabled) { 699 mEnabled = enabled; 700 return this; 701 } 702 703 /** 704 * Set whether this item is selectable. 705 * @param selectable 706 */ 707 @NonNull setSelectable(boolean selectable)708 public RowBuilder setSelectable(boolean selectable) { 709 mSelectable = selectable; 710 return this; 711 } 712 713 /** 714 * 715 */ iconNeedsToBeProcessed()716 public boolean iconNeedsToBeProcessed() { 717 return mIconNeedsToBeProcessed; 718 } 719 720 /** 721 * 722 */ getButtonStyle()723 public int getButtonStyle() { 724 return mButtonStyle; 725 } 726 727 /** 728 * Get the target slice uri. 729 */ getTargetSliceUri()730 public CharSequence getTargetSliceUri() { 731 return mTargetSliceUri; 732 } 733 734 /** Get the key for the builder */ getKey()735 public CharSequence getKey() { 736 return mKey; 737 } 738 getUri()739 public Uri getUri() { 740 return mUri; 741 } 742 hasEndActionOrToggle()743 public boolean hasEndActionOrToggle() { 744 return mHasEndActionOrToggle; 745 } 746 hasEndImage()747 public boolean hasEndImage() { 748 return mHasEndImage; 749 } 750 hasDefaultToggle()751 public boolean hasDefaultToggle() { 752 return mHasDefaultToggle; 753 } 754 getRadioGroup()755 public CharSequence getRadioGroup() { 756 return mRadioGroup; 757 } 758 isEnabled()759 public boolean isEnabled() { 760 return mEnabled; 761 } 762 isSelectable()763 public boolean isSelectable() { 764 return mSelectable; 765 } 766 isTitleItemLoading()767 public boolean isTitleItemLoading() { 768 return mTitleItemLoading; 769 } 770 getTitleIcon()771 public IconCompat getTitleIcon() { 772 return mTitleIcon; 773 } 774 getTitleAction()775 public SliceAction getTitleAction() { 776 return mTitleAction; 777 } 778 getPrimaryAction()779 public SliceAction getPrimaryAction() { 780 return mPrimaryAction; 781 } 782 getFollowupAction()783 public SliceAction getFollowupAction() { 784 return mFollowupAction; 785 } 786 getActionId()787 public int getActionId() { 788 return mActionId; 789 } 790 getPageId()791 public int getPageId() { 792 return mPageId; 793 } 794 getTitle()795 public CharSequence getTitle() { 796 return mTitle; 797 } 798 isTitleLoading()799 public boolean isTitleLoading() { 800 return mTitleLoading; 801 } 802 getSubtitle()803 public CharSequence getSubtitle() { 804 return mSubtitle; 805 } 806 isSubtitleLoading()807 public boolean isSubtitleLoading() { 808 return mSubtitleLoading; 809 } 810 getContentDescription()811 public CharSequence getContentDescription() { 812 return mContentDescription; 813 } 814 getLayoutDirection()815 public int getLayoutDirection() { 816 return mLayoutDirection; 817 } 818 getInfoText()819 public CharSequence getInfoText() { 820 return mInfoText; 821 } 822 getInfoImage()823 public IconCompat getInfoImage() { 824 return mInfoImage; 825 } 826 getEndItems()827 public List<Object> getEndItems() { 828 return mEndItems; 829 } 830 getInfoItems()831 public List<Pair<String, String>> getInfoItems() { 832 return mInfoItems; 833 } 834 getEndTypes()835 public List<Integer> getEndTypes() { 836 return mEndTypes; 837 } 838 getEndLoads()839 public List<Boolean> getEndLoads() { 840 return mEndLoads; 841 } 842 isTitleActionLoading()843 public boolean isTitleActionLoading() { 844 return mTitleActionLoading; 845 } 846 } 847 } 848