Skip to content

Commit

Permalink
[TabLayout] Add selectedTabTextAppearance attribute
Browse files Browse the repository at this point in the history
Resolves #2159

PiperOrigin-RevId: 477238120
  • Loading branch information
imhappi authored and pekingme committed Sep 27, 2022
1 parent 1322e61 commit 00220d0
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 9 deletions.
16 changes: 10 additions & 6 deletions docs/components/Tabs.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,12 +361,16 @@ Element | Attribute | Related method(s)

### Tab item text label attributes

Element | Attribute | Related method(s) | Default value
---------------- | ------------------- | --------------------------------------------------------------- | -------------
**Text** | `android:text` | `setText`<br>`getText` | `null`
**Color** | `tabTextColor` | `setTabTextColors`<br>`getTabTextColors` | `colorOnSurfaceVariant` and `colorPrimary` (activated) (see all [states](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/res/color/m3_tabs_icon_color.xml))
**Typography** | `tabTextAppearance` | N/A | `?attr/textAppearanceLabelLarge`
**Inline label** | `tabInlineLabel` | `setInlineLabel`<br>`setInlineLabelResource`<br>`isInlineLabel` | `false`
Element | Attribute | Related method(s) | Default value
------------------------- | --------------------------- | --------------------------------------------------------------- | -------------
**Text** | `android:text` | `setText`<br>`getText` | `null`
**Color** | `tabTextColor` | `setTabTextColors`<br>`getTabTextColors` | `colorOnSurfaceVariant` and `colorPrimary` (activated) (see all [states](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/res/color/m3_tabs_icon_color.xml))
**Typography** | `tabTextAppearance` | N/A | `?attr/textAppearanceLabelLarge`
**Active tab typography** | `selectedTabTextAppearance` | N/A | None; will use `tabTextAppearance` instead
**Inline label** | `tabInlineLabel` | `setInlineLabel`<br>`setInlineLabelResource`<br>`isInlineLabel` | `false`

**Note:** When using `selectedTabTextAppearance`, you must have matching text
attributes in `tabTextAppearance` to avoid unintended behavior.

### Tab item container attributes

Expand Down
59 changes: 56 additions & 3 deletions lib/java/com/google/android/material/tabs/TabLayout.java
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,9 @@ public interface BaseOnTabSelectedListener<T extends Tab> {
int tabPaddingEnd;
int tabPaddingBottom;

int tabTextAppearance;
private final int defaultTabTextAppearance;
private final int tabTextAppearance;
private int selectedTabTextAppearance = -1;
ColorStateList tabTextColors;
ColorStateList tabIconTint;
ColorStateList tabRippleColorStateList;
Expand All @@ -460,6 +462,7 @@ public interface BaseOnTabSelectedListener<T extends Tab> {

android.graphics.PorterDuff.Mode tabIconTintMode;
float tabTextSize;
float selectedTabTextSize;
float tabTextMultiLineSize;

final int tabBackgroundResId;
Expand Down Expand Up @@ -566,6 +569,11 @@ public TabLayout(@NonNull Context context, @Nullable AttributeSet attrs, int def
tabPaddingBottom =
a.getDimensionPixelSize(R.styleable.TabLayout_tabPaddingBottom, tabPaddingBottom);

if (ThemeEnforcement.isMaterial3Theme(context)) {
defaultTabTextAppearance = R.attr.textAppearanceLabelLarge;
} else {
defaultTabTextAppearance = R.attr.textAppearanceButton;
}
tabTextAppearance =
a.getResourceId(R.styleable.TabLayout_tabTextAppearance, R.style.TextAppearance_Design_Tab);

Expand All @@ -586,6 +594,43 @@ public TabLayout(@NonNull Context context, @Nullable AttributeSet attrs, int def
ta.recycle();
}

if (a.hasValue(R.styleable.TabLayout_tabSelectedTextAppearance)) {
selectedTabTextAppearance =
a.getResourceId(R.styleable.TabLayout_tabSelectedTextAppearance, tabTextAppearance);
}

if (selectedTabTextAppearance != -1) {
// If there is a selected tab text appearance specified, we take the selected tab text size
// and selected color from it.
@SuppressLint("CustomViewStyleable")
final TypedArray selectedTabTA =
context.obtainStyledAttributes(
selectedTabTextAppearance, androidx.appcompat.R.styleable.TextAppearance);

try {
selectedTabTextSize =
selectedTabTA.getDimensionPixelSize(
androidx.appcompat.R.styleable.TextAppearance_android_textSize,
(int) tabTextSize);
ColorStateList selectedTabTextColor =
MaterialResources.getColorStateList(
context,
selectedTabTA,
androidx.appcompat.R.styleable.TextAppearance_android_textColor);
// Merge the selected tab color if it's set in the selected tab text appearance.
if (selectedTabTextColor != null) {
tabTextColors =
createColorStateList(
tabTextColors.getDefaultColor(),
selectedTabTextColor.getColorForState(
new int[] {android.R.attr.state_selected},
selectedTabTextColor.getDefaultColor()));
}
} finally {
selectedTabTA.recycle();
}
}

if (a.hasValue(R.styleable.TabLayout_tabTextColor)) {
// If we have an explicit text color set, use it instead
tabTextColors =
Expand Down Expand Up @@ -1900,11 +1945,14 @@ public void selectTab(@Nullable final Tab tab, boolean updateIndicator) {
// Setting selectedTab before dispatching 'tab unselected' events, so that currentTab's state
// will be interpreted as unselected
selectedTab = tab;
if (currentTab != null) {
// If the current tab is still attached to the TabLayout.
if (currentTab != null && currentTab.parent != null) {
dispatchTabUnselected(currentTab);
currentTab.view.update();
}
if (tab != null) {
dispatchTabSelected(tab);
tab.view.update();
}
}
}
Expand Down Expand Up @@ -2690,7 +2738,12 @@ final void update() {
inflateAndAddDefaultTextView();
defaultMaxLines = TextViewCompat.getMaxLines(this.textView);
}
TextViewCompat.setTextAppearance(this.textView, tabTextAppearance);
TextViewCompat.setTextAppearance(this.textView, defaultTabTextAppearance);
if (isSelected() && selectedTabTextAppearance != -1) {
TextViewCompat.setTextAppearance(this.textView, selectedTabTextAppearance);
} else {
TextViewCompat.setTextAppearance(this.textView, tabTextAppearance);
}
if (tabTextColors != null) {
this.textView.setTextColor(tabTextColors);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<public name="tabStyle" type="attr"/>
<public name="tabSecondaryStyle" type="attr"/>
<public name="tabTextAppearance" type="attr"/>
<public name="tabSelectedTextAppearance" type="attr"/>
<public name="tabTextColor" type="attr"/>
<public name="Widget.Design.TabLayout" type="style"/>
<public name="Widget.MaterialComponents.TabLayout" type="style"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@
<!-- {@deprecated Instead, provide a ColorStateList to the tabTextColor attribute with a
selected color set.} -->
<attr name="tabSelectedTextColor" format="color"/>
<!-- A reference to a TextAppearance style to be applied to selected tab. -->
<attr name="tabSelectedTextAppearance" format="reference"/>
<!-- The preferred padding along the start edge of tabs. -->
<attr name="tabPaddingStart" format="dimension"/>
<!-- The preferred padding along the top edge of tabs. -->
Expand Down

0 comments on commit 00220d0

Please sign in to comment.