【问题标题】:Custom TextSize of BottomNavigationView support androidBottomNavigationView的自定义TextSize支持android
【发布时间】:2016-10-21 08:49:48
【问题描述】:

我正在尝试从 android 支持库 25.0.0 更改 BottomNavigationView 的 textSize

<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>

我有什么遗漏的吗?

【问题讨论】:

  • design_bottom_navigation_item.xml 在 extras design sdk 文件夹中不存在。我无法覆盖它。
  • 我相信你的 TextStyleBNV 应该有属性parent="TextAppearance.AppCompat"

标签: android android-support-library androiddesignsupport


【解决方案1】:

不幸的是,BottomNavigationView 的第一个版本有很多限制。现在,您无法仅使用支持设计 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。所以要小心。

【讨论】:

  • @Sanf0rd 我想为其他属性做类似的事情,但不知道在哪里搜索名称以添加样式覆盖。你能指点我在哪里看吗? // 旁注:当菜单中有 5 个项目时,我想更改所选底部导航项目的侧边距。它看起来比指南上显示的要大,实施“官方”解决方案的奇怪方式..
  • 我刚刚在bottomNavigation的内部类和布局文件里面搜了一下。
  • 此外,如果无效,您必须在该 dimens.xml 中添加命名空间。喜欢 schemas.android.com/tools">....</resources>
  • 如何设置字体为title和SingleLine=false?
  • 它在 androidx com.google.android.material.bottomnavigation.BottomNavigationView 中不起作用
【解决方案2】:

您可以通过为组件属性itemTextAppearanceActiveitemTextAppearanceInactive 定义自己的样式来更改BottomNavigationView 文本外观。默认情况下,他们有textAppearanceCaption 检查文档Bottom Navigation 中的主题属性映射部分。

<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" />

styles.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>
  • 接下来,更改选定的文本颜色和图标
    只需在可绘制对象上创建 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 中设置此颜色
  • 完成,尝试查看您的导航底部。颜色图标和文本将发生变化。 ?

【讨论】:

  • 有效,但它也会重置各种属性,例如文本的颜色。是否可以仅更改文本大小?
  • @androiddeveloper 你可以将你的应用主题设置为父主题,它会从你的应用主题中挑选颜色。
  • 什么的父母?你的意思是活动主题?请解释一下。
  • 请注意,您不需要创建 2 种不同的样式。只需两次应用相同的。
  • 我使用了 AppCompat 主题的公认答案并且有效,但由于使用 Chips Group,我需要切换到 Material Component 主题并且它不再有效。在这种情况下,您的 Text 方法有助于将样式设置为文本,而不是使用覆盖的尺寸。非常感谢 +1。
【解决方案3】:

你可以像这样改变它。你只需要知道谷歌支持使用的标签的 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

【讨论】:

    【解决方案4】:

    我使用下面的 sn-p 来改变使用 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" />
    

    【讨论】:

      【解决方案5】:

      另一种解决方案是使用 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;
                  }
              }
      }
      

      然后设置任意菜单项的跨度...

      @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;
                  }
              });
      

      【讨论】:

        【解决方案6】:

        为此,我只是决定覆盖导航项布局:

        <?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

        【讨论】:

        • 你是认真的吗?
        【解决方案7】:

        在 UpdateBarTextColor 中添加 TabTextStyle 代码(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> 
        

        【讨论】:

          【解决方案8】:

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

          最后,我能够通过为 menu.xml 中使用的每个标题字符串资源使用 &lt;font size="8"&gt;&lt;/font&gt; 标记来更改文本大小。

          例如,我在这里声明了一个菜单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 中...?
          • 不,字符串声明中的字体标签对我不起作用。 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 膨胀错误
          • 不要使用这种方法。它以某种方式适用于我的罕见案例。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多