From 00220d0ad636355b7c9c54c6a1aad64550db5897 Mon Sep 17 00:00:00 2001 From: rightnao Date: Tue, 27 Sep 2022 19:02:07 +0000 Subject: [PATCH] [TabLayout] Add selectedTabTextAppearance attribute Resolves https://github.com/material-components/material-components-android/issues/2159 PiperOrigin-RevId: 477238120 --- docs/components/Tabs.md | 16 +++-- .../android/material/tabs/TabLayout.java | 59 ++++++++++++++++++- .../tabs/res-public/values/public.xml | 1 + .../material/tabs/res/values/attrs.xml | 2 + 4 files changed, 69 insertions(+), 9 deletions(-) diff --git a/docs/components/Tabs.md b/docs/components/Tabs.md index ab2b7b1c15a..a9986e457ca 100644 --- a/docs/components/Tabs.md +++ b/docs/components/Tabs.md @@ -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`
`getText` | `null` -**Color** | `tabTextColor` | `setTabTextColors`
`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`
`setInlineLabelResource`
`isInlineLabel` | `false` +Element | Attribute | Related method(s) | Default value +------------------------- | --------------------------- | --------------------------------------------------------------- | ------------- +**Text** | `android:text` | `setText`
`getText` | `null` +**Color** | `tabTextColor` | `setTabTextColors`
`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`
`setInlineLabelResource`
`isInlineLabel` | `false` + +**Note:** When using `selectedTabTextAppearance`, you must have matching text +attributes in `tabTextAppearance` to avoid unintended behavior. ### Tab item container attributes diff --git a/lib/java/com/google/android/material/tabs/TabLayout.java b/lib/java/com/google/android/material/tabs/TabLayout.java index 1f8b50c89e0..8f32dbf60b0 100644 --- a/lib/java/com/google/android/material/tabs/TabLayout.java +++ b/lib/java/com/google/android/material/tabs/TabLayout.java @@ -451,7 +451,9 @@ public interface BaseOnTabSelectedListener { int tabPaddingEnd; int tabPaddingBottom; - int tabTextAppearance; + private final int defaultTabTextAppearance; + private final int tabTextAppearance; + private int selectedTabTextAppearance = -1; ColorStateList tabTextColors; ColorStateList tabIconTint; ColorStateList tabRippleColorStateList; @@ -460,6 +462,7 @@ public interface BaseOnTabSelectedListener { android.graphics.PorterDuff.Mode tabIconTintMode; float tabTextSize; + float selectedTabTextSize; float tabTextMultiLineSize; final int tabBackgroundResId; @@ -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); @@ -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 = @@ -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(); } } } @@ -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); } diff --git a/lib/java/com/google/android/material/tabs/res-public/values/public.xml b/lib/java/com/google/android/material/tabs/res-public/values/public.xml index 258c4dd8f60..ac3a60d1f36 100644 --- a/lib/java/com/google/android/material/tabs/res-public/values/public.xml +++ b/lib/java/com/google/android/material/tabs/res-public/values/public.xml @@ -41,6 +41,7 @@ + diff --git a/lib/java/com/google/android/material/tabs/res/values/attrs.xml b/lib/java/com/google/android/material/tabs/res/values/attrs.xml index e3621918a1a..f9a20c32639 100644 --- a/lib/java/com/google/android/material/tabs/res/values/attrs.xml +++ b/lib/java/com/google/android/material/tabs/res/values/attrs.xml @@ -96,6 +96,8 @@ + +