TextAllCaps = “ false”不适用于 TabLayout 设计支持

我已经设置了 android:textAllCaps="false"在我的 android.support.design.widget.TabLayout认为它是显示标签标题在所有大写只。

我怎样才能移除所有的大写字母?

70701 次浏览

UPDATE FOR DESIGN LIBRARY 23.2.0+

The original answer doesn't work with design library 23.2.0 or later. Thanks for @fahmad6 pointed out in comment, in case someone missed that comment, I'll put it here. You need to set both textAllCaps and android:textAllCaps to false to disable all capitalize setting.

<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
<item name="android:textAllCaps">false</item>
</style>

ORIGINAL ANSWER

By default, tabs are created by TabLayout sets the textAllCaps property to be true, you have to define a style making this flag false.

<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">@style/MyCustomTextAppearance</item>
</style>


<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>

In versions priror to 14, you need to set (as commented by Paresh Mayani):

<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">@style/MyCustomTextAppearance</item>
</style>


<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>

But, in case of android version is equal or greater than 14, you need to set:

<item name="android:textAllCaps">false</item>

So, if you need to be compatible with versions before and after 14, you also need to create a folder values-v14, and a file styles.xml in that folder with the content:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textAllCaps">false</item>
</style>
</resources>

You can also do this in your Java code. If you are using a SlidingTabLayout look at this sample:

protected TextView createDefaultTabView(Context context){
TextView textView = new TextView(context);
textView.setGravity(Gravity.CENTER);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);//see line 38 above change the value their in TAB_VIEW_TEXT_SIZE_SP.
textView.setTypeface(Typeface.DEFAULT);//From DEFAULT_BOLD
textView.setTextColor(Color.parseColor("#536DFE"));//Text color of the words in the tabs. Indigo A200


if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
// If we're running on Honeycomb or newer, then we can use the Theme's
// selectableItemBackground to ensure that the View has a pressed state
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
textView.setBackgroundResource(outValue.resourceId);
}


if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){
// If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
textView.setAllCaps(true);
}


int padding = (int)(TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
textView.setPadding(padding, padding, padding, padding);


return textView;
}

Notice that textView.setAllCaps() has true as the perimeter:

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){
// If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
textView.setAllCaps(true);
}

When I changed this to (false) it solved the problem for me:

textView.setAllCaps(false);

Also my string resource file that I use for the tabs looks like this:

<string name="tab_title">Title with capital and smaller case</string>

However if it had all caps like >TITLE WITH ALL CAPS< you would still of course get all caps in your tabs.

I made no other changes.

It is noteworthy that you can set textView.setAllCaps(false) too, but this made no difference in my case. I just commented out textView.setAllCaps(true).

@Paresh Mayani answer is correct however you can create only tab style

<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>

And use it using

<android.support.design.widget.TabLayout
app:tabTextAppearance="@style/MyCustomTextAppearance"
.../>

https://stackoverflow.com/a/34678235/1025379

<android.support.design.widget.TabLayout
app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"
/>

Here is simple solution....Enjoy

 for (int tabIndex = 0; tabIndex <tabLayout.getTabCount() ; tabIndex++) {
TextView tabTextView = (TextView)(((LinearLayout)((LinearLayout)tabLayout.getChildAt(0)).getChildAt(tabIndex)).getChildAt(1));
tabTextView.setAllCaps(false);
}

use this attribute app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget" It will work.

  <android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:tabGravity="fill"
app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"
app:tabIndicatorColor="@color/colorPrimary"
app:tabMode="fixed"
app:tabPaddingStart="0dp" />

For those who can't get working other answers.

Defining a style is working fine when you have single line tab text. If you take a close look into the TabLayout, you'll see that it's using a field design_tab_text_size_2line when the tabs has more than one line.

The only way I could find to effect this field is to override it in your dimen file.

So put this in your values/dimens.xml

<dimen name="design_tab_text_size_2line" tools:override="true">10sp</dimen>

Hope it helps.

Try following method and you can implement all the methods of TextView in TabLayout

private void setCustomTab() {


ViewGroup vg = (ViewGroup) mTabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildsCount = vgTab.getChildCount();
for (int i = 0; i < tabChildsCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(ResourcesCompat.getFont(this,R.font.montserrat_medium));
((TextView) tabViewChild).setAllCaps(false);
}
}
}
}

Hope it helps.

In my case two variants work:

1) By Bogdan (susemi99):

<android.support.design.widget.TabLayout
app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"
/>

2) By Paresh Mayani. I wanted to have android:textAllCaps="false" and android:textSize="15sp" simultaneously, so his old method works.

In styles.xml write (parent may vary, for instance, "@android:style/TextAppearance.Widget.TabWidget", "TextAppearance.Design.Tab"):

<style name="TabLayout" parent="Widget.Design.TabLayout">
<item name="tabIndicatorColor">@color/color_blue</item>
<item name="tabSelectedTextColor">@color/color_blue</item>
<item name="tabTextColor">@color/black</item>
<item name="tabTextAppearance">@style/TabLayoutTextAppearance</item>
</style>


<style name="TabLayoutTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textSize">15sp</item>
<item name="textAllCaps">false</item>
<item name="android:textAllCaps">false</item>
</style>

Apply this style in layout:

<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TabLayout"
/>

Change: <item name="android:textAllCaps">false</item>

With: <item name="textAllCaps">false</item>

This Worked For Me...

<style name="TabLayoutStyle" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">@style/TabTextAppearance</item>
</style>


<style name="TabTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>

Just add this to your custom style file

<item name="android:textStyle">normal</item>

I read all the above solutions and all lead to this.

Changing attributes in XML file doesn't work in Android 11 (SDK 30). Here is code that I use to setup tabs individually using a tab label. It's safer than setting new styles for all text fields in the tabs or relying on the existing tab layout, because the current tab design can be changed by Android. This method assumes that a tab text has been set before the function below is called. Second parameter in the call, txt is a tab label.

private fun setTabStyle(tabs: TabLayout, txt: String) {
val av = ArrayList<View?>()
tabs.findViewsWithText(av, txt, View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION )
if (av.count() > 0) {
val avt = ArrayList<View?>()
(av[0] as? ViewGroup)?.let {
for ( i in 0 until it.childCount) {
val tv = it.getChildAt(i) as? TextView
tv?.let {t ->
if (tv.text == txt) {
t.isAllCaps = false
t.setTextSize(TypedValue.COMPLEX_UNIT_SP, 11.toFloat())


}
}


}


}
}


}

This works for me in just one line

 <android.support.design.widget.TabLayout
app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"/>

Long story short (programmatically)...

/**
* @param view Target TabLayout view
* @param caps Present the text caps style
*/
public static void setAllCaps(View view, boolean caps) {
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
setAllCaps(((ViewGroup) view).getChildAt(i),caps);
} else if (view instanceof TextView) ((TextView) view).setAllCaps(caps);
}

Call setAllCaps like this :

    tabLayout.addTab(tabLayout.newTab().setText("Recent"));
tabLayout.addTab(tabLayout.newTab().setText("New"));
setAllCaps(tabLayout,false);

enter image description here

It'll work if you only add one of these calls.


        app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"
        

app:tabTextAppearance="@style/TextAppearance.AppCompat.Medium"
        

app:tabTextAppearance="@style/TextAppearance.AppCompat.Small"