BottomNavigationView的自定义TextSize支持Android

73

我正在尝试更改来自Android支持库25.0.0的BottomNavigationView的文本大小

<android.support.design.widget.BottomNavigationView
        android:id="@+id/bottom_navigation_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@color/colorPrimaryDark"
        android:foregroundTint="@color/colorAccent"
        app:itemIconTint="@android:color/white"
        app:itemTextColor="@android:color/white"
        app:layout_anchor="@id/lyt_container"
        app:layout_anchorGravity="bottom"
        app:itemTextAppearance="@style/TextStyleBNV"
        app:menu="@menu/nav_menu" />

<style name="TextStyleBNV">
        <item name="android:textSize">@dimen/twelve_sp</item>
        <item name="android:padding">0dp</item>
        <item name="textAllCaps">false</item>
    </style>

我有什么遗漏吗。


请参考以下链接:https://dev59.com/Y10Z5IYBdhLWcg3wphwE - sasikumar
design_bottom_navigation_item.xml不在extras design sdk文件夹中,我无法覆盖它。 - silentsudo
我相信你的TextStyleBNV应该具有属性parent="TextAppearance.AppCompat" - Cauê Jannini
8个回答

174

不幸的是,这个底部导航栏的第一个版本存在很多限制。目前,您无法仅使用支持设计API更改标题大小。因此,在谷歌未实现此功能之前,您可以采取以下措施来解决这个限制:

在您的dimen.xml文件中添加:

    <dimen name="design_bottom_navigation_text_size" tools:override="true">30sp</dimen>
    <dimen name="design_bottom_navigation_active_text_size" tools:override="true">30sp</dimen>

这样做会覆盖BottomNavigationView内部类使用的dimen默认值,因此要小心。


2
@Sanf0rd 我想对其他属性做类似的事情,但不知道在哪里搜索要添加样式覆盖的名称。你能告诉我去哪里找吗?// 顺便说一下:当菜单中有5个项目时,我想更改所选BottomNavigation项的侧边填充。它看起来比指南中显示的要大得多,这是实现“官方”解决方案的奇怪方式。 - quezak
1
我刚刚在底部导航的内部类和布局文件中进行了搜索。 - Sanf0rd
3
如果无效,您需要在dimens.xml中添加命名空间。 类似于<resources xmlns:tools="http://schemas.android.com/tools"> ... </resources>。 - CodeToLife
14
它在androidx中不起作用。com.google.android.material.bottomnavigation.BottomNavigationView - denizs
1
如果有人正在寻找可以覆盖的所有其他维度,请访问以下链接:https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/bottomnavigation/res/values/dimens.xml - Domenico
显示剩余7条评论

101

您可以通过为组件属性itemTextAppearanceActiveitemTextAppearanceInactive定义自己的样式来更改BottomNavigationView的文本外观。默认情况下,它们具有textAppearanceCaption。请在文档的Theme Attribute Mapping部分中查看底部导航栏

<android.support.design.widget.BottomNavigationView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:itemTextAppearanceActive="@style/BottomNavigationView.Active"
    app:itemTextAppearanceInactive="@style/BottomNavigationView"
    app:menu="@menu/bottom_navigation_main" />

样式.xml

<style name="BottomNavigationView" parent="@style/TextAppearance.AppCompat.Caption">
    <item name="android:textSize">10sp</item>
</style>

<style name="BottomNavigationView.Active" parent="@style/TextAppearance.AppCompat.Caption">
    <item name="android:textSize">11sp</item>
</style>
  • 接下来,更改文本颜色选择和图标:
    只需在drawable上创建bottom_nav_icon_color_selectorbottom_nav_text_color_selector以编辑默认值即可。

  • 要更改图标颜色 - bottom_nav_icon_color_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorPrimary" android:state_checked="true" /> <!-- colorIcon Active -->
    <item android:color="@color/colorPrimary" android:state_enabled="true" android:state_pressed="true" /> <!-- colorIcon Active -->
    <item android:color="@color/colorIconInActive" /> <!-- colorIcon InActive -->
</selector>
  • 更改文本颜色 - bottom_nav_text_color_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorPrimary" android:state_checked="true" /> <!-- colorText Active -->
    <item android:color="@color/colorPrimary" android:state_enabled="true" android:state_pressed="true" /> <!-- colorText Active -->
    <item android:color="@color/colorTextInActive" /> <!-- colorText InActive -->
</selector>
  • 注意 : @color/colorIconInActive 是一个禁用/不活动的颜色,您可以在res-values-colors中设置此颜色
  • 完成后,请尝试查看您的底部导航栏。颜色图标和文本将更改。

1
可以实现,但这也会重置一些属性,比如文本的颜色。有没有可能只改变文本大小? - android developer
@androiddeveloper 你可以将应用程序主题设置为父级,它会从您的应用程序主题选择颜色。 - Volodymyr
1
父级是什么?您是指Activity主题吗?请解释一下。 - android developer
1
请注意,您无需创建两种不同的样式。只需应用相同的样式两次即可。 - Albert Vila Calvo
1
我使用了带有AppCompat主题的被接受的答案,那个方案可行,但是由于使用了Chips Group,我需要切换到Material Component主题,结果不再起作用。你的setText方法对于设置文本样式非常有帮助,而不是使用重载dimens。非常感谢 +1。 - MRamzan
在我的情况下,接受的答案没有起作用。这个由@Volodymyr提供的答案应该被标记为接受的答案,在我的情况下,它对com.google.android.material.bottomnavigation.BottomNavigationView起作用。 - undefined

17
我使用下面的代码片段来使用Material设计更改NavigationView样式。
<style name="MyBottomNavigationView" parent="Widget.MaterialComponents.BottomNavigationView">
    <item name="itemIconTint">@color/bottom_navigation_item_selector</item>
    <item name="itemTextColor">@color/bottom_navigation_item_selector</item>
    <item name="itemTextAppearanceActive">@style/MyBottomNavigationView.TextAppearance</item>
    <item name="itemTextAppearanceInactive">@style/MyBottomNavigationView.TextAppearance</item>
</style>

<style name="MyBottomNavigationView.TextAppearance" parent="TextAppearance.MaterialComponents.Caption">
    <item name="android:textSize">11sp</item>
    <item name="fontFamily">@font/exo2_medium</item>
</style>

然后将样式设置为BottomNavigationView元素

<com.google.android.material.bottomnavigation.BottomNavigationView
    ...
    style="@style/MyBottomNavigationView" />

16

你可以像这样进行更改。你只需要知道谷歌支持使用的标签的ID。

BottomNavigationView bottomNavigationView = (BottomNavigationView) fragmentActivity.findViewById(R.id.bottom_navigation);
    TextView textView = (TextView) bottomNavigationView.findViewById(R.id.menu_item_home).findViewById(R.id.largeLabel);
    textView.setTextSize(8);

LargeLabel是Google在其库中使用的标签的ID。


2
另一个解决方案是使用Spannable来调整文本的大小、颜色、字体或其他属性。...
private static class MenuSpannable extends MetricAffectingSpan{
        int color = Color.RED;
        int size = 40;

        public MenuSpannable() {
            setSelected(false);
        }

        @Override
        public void updateMeasureState(TextPaint p) {
            p.setColor(color);
            p.setTextSize(size);
            /* p.setText --- whatever --- */
        }

        @Override
        public void updateDrawState(TextPaint tp) {
            tp.setColor(color);
            tp.setTextSize(size);
            /* tp.setText --- whatever --- */
        }
        private void setSelected(boolean selected){
            if(selected){
                color = Color.RED;
                size = 40;
            }else{
                color = Color.BLUE;
                size = 20;
            }
        }
}

然后为任何菜单项设置span...
@Override
protected void onCreate(Bundle savedInstanceState) {
        BottomNavigationView mBottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_menu);
        final Menu menu = mBottomNavigationView.getMenu();
        final Font font = Font.getFromContext(this);
        for(int i = 0; i < menu.size(); i++) {
            SpannableString spannableString = new SpannableString(menu.getItem(i).getTitle());
            spannableString.setSpan(new MenuSpannable(),0,spannableString.length(),0);
            menu.getItem(i).setTitle(spannableString);
        }
}

如果您希望文本随选择状态而更改
mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
             Menu menu = mBottomNavigationView.getMenu();
             for(int i = 0; i < menu.size(); i++) {
                MenuSpannable menuSpannable = new MenuSpannable();
                menuSpannable.setSelected(item.getItemId() == menu.getItem(i).getItemId());
                SpannableString sString = new SpannableString(menu.getItem(i).getTitle());
                sString.setSpan(menuSpannable,0,sString.length(),0);
                menu.getItem(i).setTitle(sString);
                }
            return false;
            }
        });

1
为了实现这一点,我决定覆盖导航项布局:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
        android:id="@+id/icon"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="@dimen/design_bottom_navigation_margin"
        android:layout_marginBottom="@dimen/design_bottom_navigation_margin"
        android:duplicateParentState="true" />
    <android.support.design.internal.BaselineLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:clipToPadding="false"
        android:paddingBottom="10dp"
        android:duplicateParentState="true">
        <TextView
            android:id="@+id/smallLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="@dimen/design_bottom_navigation_text_size"
            android:singleLine="true"
            android:duplicateParentState="true" />
        <TextView
            android:id="@+id/largeLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="invisible"
            android:textSize="@dimen/design_bottom_navigation_active_text_size"
            android:singleLine="true"
            android:duplicateParentState="true" />
    </android.support.design.internal.BaselineLayout>
</merge>

请确保将其命名为design_bottom_navigation_item。


3
你是认真的吗? - Serg Burlaka

-1
将TabTextStyle代码添加到UpdateBarTextColor中(此void存在于BottomBarPageRenderer中)。
 void UpdateBarTextColor()
    {
        if (_disposed || _bottomBar == null)
        {
            return;
        }
        //This is linked to styles.xml to set size of text
        _bottomBar.SetTextAppearance(Resource.Style.TabTextStyle);
        //Set color of text and icon in BottomNavBar
        _bottomBar.SetActiveTabColor(Element.BarTextColor.ToAndroid(Color.FromHex("#0094F0")));
        // The problem SetActiveTabColor does only work in fiexed mode // haven't found yet how to set text color for tab items on_bottomBar, doesn't seem to have a direct way
    }

然后将其添加到styles.xml中:

<style name="TabTextStyle" parent="@android:style/TextAppearance.Medium"> 
    <item name="android:textSize">8dp</item> 
</style> 

-5

不幸的是,在com.android.support:design:28.0.0中覆盖dimen对我没有起作用。

最终,我通过在menu.xml中使用<font size="8"></font>标签来更改每个标题字符串资源的文本大小。

例如,我在这里声明了一个菜单menu_bottom_navigation.xml,其中包含以下项目:

<item
  ...
  android:title="@string/main_navi_item_home"
  .../>

string.xml 中,设置目标资源的方式如下:

<string name="main_navi_item_home"><font size="8">Home</font></string>

"8" 是什么?它是在 dp 中还是 sp 中...? - android developer
没有用字符串声明中的字体标签对我起作用。java.lang.RuntimeException: 无法启动活动ComponentInfo{ca.ami.android.amiandroid/ca.ami.android.amiandroid.activities.MainActivityTV}: android.view.InflateException: 二进制XML文件行#28:二进制XML文件行#28:错误膨胀类android.support.design.widget.BottomNavigationView。 - Kornilov Ruslan
不要使用这个方法。它在我的极少数情况下不知怎么就起作用了。 - KinoP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接