BottomNavigationView 具有超过 3 个项目:选项卡标题被隐藏

BottomNavigationView with more than 3 Items: tab title is hiding

我正在使用 BottomNavigationView 并使用 Android 支持设计库 25。 但是当我切换标签时,另一个标签的标题被隐藏了。但是实际的底部导航视图没有隐藏问题。但是我的藏起来了。

但我希望它看起来像那样。有什么想法吗?我错过了什么?

这是我的代码:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.yunus.ototakip.MainActivity">

<FrameLayout
    android:id="@+id/main_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/bottom_navigation"
    android:layout_alignParentTop="true">
</FrameLayout>

<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    app:itemBackground="@color/colorPrimary"
    app:itemIconTint="@color/beyaz"
    app:itemTextColor="@color/beyaz"
    app:menu="@menu/bottombar_menu" />

bottom_bar_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
 <item
android:id="@+id/bb_menu_arac"
android:enabled="true"
android:icon="@drawable/icon_car"
android:title="@string/araclarim"
app:showAsAction="ifRoom" />
 <item
android:id="@+id/bb_menu_yakin"
android:enabled="true"
android:icon="@drawable/icon_yer"
android:title="@string/yakinimdakiler"
app:showAsAction="ifRoom" />
  <item
android:id="@+id/bb_menu_yaklasan"
android:enabled="true"
android:icon="@drawable/icon_takvim"
android:title="@string/yaklasanlar"
app:showAsAction="ifRoom" />

<item
    android:id="@+id/bb_menu_ipucu"
    android:enabled="true"
    android:icon="@drawable/icon_ipucu"
    android:title="@string/ipuclari"
    app:showAsAction="ifRoom" />
 </menu>

更新

removeShiftMode() 不再需要,因为在支持库 28.0.0-alpha1 中我们现在可以添加 Labels.

在XML中:

<android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />

对于以编程方式更改:

mBottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); 

为此工作:将设计支持库更新为 28.0.0-alpha1

这是一个好东西read

对于较旧的支持库:

在您的 bottom_bar_menu.xml 中。更改 showAsAction 属性

<item android:id="@id/menu_item"
android:title="text"
android:icon="@drawable/drawable_resource_name"
android:showAsAction="always|withText" />

在build.gradle中:

compile 'com.android.support:design:25.3.1'

底部导航查看超过 3 个项目:使用 removeShiftMode() 方法

BottomNavigationViewHelper.java中使用:

import android.annotation.SuppressLint;
import android.support.design.internal.BottomNavigationItemView;
import android.support.design.internal.BottomNavigationMenuView;
import android.support.design.widget.BottomNavigationView;
import java.lang.reflect.Field;

    public class BottomNavigationViewHelper {
        @SuppressLint("RestrictedApi")
        public static void removeShiftMode(BottomNavigationView view) {
            BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
            try {
                Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
                shiftingMode.setAccessible(true);
                shiftingMode.setBoolean(menuView, false);
                shiftingMode.setAccessible(false);
                for (int i = 0; i < menuView.getChildCount(); i++) {
                    BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
                    //noinspection RestrictedApi
                    item.setShiftingMode(false);
                    // set once again checked value, so view will be updated
                    //noinspection RestrictedApi
                    item.setChecked(item.getItemData().isChecked());
                }
            } catch (NoSuchFieldException e) {
                Log.e("BottomNav", "Unable to get shift mode field", e);
            } catch (IllegalAccessException e) {
                Log.e("BottomNav", "Unable to change value of shift mode", e);
            }
        }
    }

使用以下方式调用它:

BottomNavigationView bottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_navigation);
BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);

它将禁用标题文本的移动动画并启用要显示的文本。

扫描BottomNavigationView源码后发现

mShiftingMode = mMenu.size() > 3;

BottomNavigationMenuView.java第265行,意思是当菜单大小超过3时,标签标题将被隐藏。 因此,如果您想显示选项卡标题,您只需要从构建中获取代码并将其更改为以下内容。

mShiftingMode = mMenu.size() > 5;

PS: BottonNavigationView 最大标签数必须在 3 到 5 之间。 您可以在 BottomNavigationViewNew 上获取代码

创建Class BottomNavigationViewHelper

import android.annotation.SuppressLint;
import android.support.design.internal.BottomNavigationItemView;
import android.support.design.internal.BottomNavigationMenuView;
import android.support.design.widget.BottomNavigationView;
import android.util.Log;
import java.lang.reflect.Field;
public class BottomNavigationViewHelper {
    @SuppressLint("RestrictedApi")
    public static void disableShiftMode(BottomNavigationView view) {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        try {
            Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
            shiftingMode.setAccessible(true);
            shiftingMode.setBoolean(menuView, false);
            shiftingMode.setAccessible(false);
if(menuView.getChildCount()<6)
           {
            for (int i = 0; i < menuView.getChildCount(); i++) {
                BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
                //noinspection RestrictedApi
                item.setShiftingMode(false);
                // set once again checked value, so view will be updated
                //noinspection RestrictedApi
                item.setChecked(item.getItemData().isChecked());
            }
         }
        } catch (NoSuchFieldException e) {
            Log.e("BNVHelper", "Unable to get shift mode field", e);
        } catch (IllegalAccessException e) {
            Log.e("BNVHelper", "Unable to change value of shift mode", e);
        }
    }
}   

通话

    BottomNavigationView bottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_navigation);
    BottomNavigationViewHelper.disableShiftMode(bottomNavigationView); 

我几乎使用了 rafsanahmad007 但将其翻译成 Kotlin。分享给未来的游子

@SuppressLint("RestrictedApi")
fun BottomNavigationView.disableShiftMode() {
    val menuView = this.getChildAt(0) as BottomNavigationMenuView
    try {
        val shiftingMode = menuView::class.java.getDeclaredField("mShiftingMode")
        shiftingMode.setAccessible(true)
        shiftingMode.setBoolean(menuView, false)
        shiftingMode.setAccessible(false)
        for (i in 0..(menuView.childCount - 1)) {
            val item = menuView.getChildAt(i) as BottomNavigationItemView
            item.setShiftingMode(false)
            // set once again checked value, so view will be updated
            item.setChecked(item.getItemData().isChecked())
        }
    } catch (e: NoSuchFieldException) {
        Timber.e("Unable to get shift mode field")
    } catch (e: IllegalAccessException) {
        Timber.e("Unable to change value of shift mode")
    }
}

使用反射的解决方案不再有效,因为字段 mShiftingMode 已被删除。

现在有一种简单的方法可以做到: 使用支持库 28 或更高版本,只需将 app:labelVisibilityMode="labeled" 添加到您的 BottomNavigationView XML 声明中。

希望对您有所帮助。

Kotlin 扩展函数:

@SuppressLint("RestrictedApi")
fun BottomNavigationView.removeShiftMode(){
    val menuView = this.getChildAt(0) as BottomNavigationMenuView
    try {
        val shiftingMode = menuView.javaClass.getDeclaredField("mShiftingMode")
        shiftingMode.isAccessible = true
        shiftingMode.setBoolean(menuView, false)
        shiftingMode.isAccessible = false
        for (i in 0 until menuView.childCount) {
            val item = menuView.getChildAt(i) as BottomNavigationItemView
            item.setShiftingMode(false)
            // set once again checked value, so view will be updated
            item.setChecked(item.itemData.isChecked)
        }
    } catch (e: NoSuchFieldException) {
        e.printStackTrace()
        Timber.tag("BottomNav").e( e, "Unable to get shift mode field")
    } catch (e: IllegalAccessException) {
        Timber.tag("BottomNav").e( e, "Unable to change value of shift mode")
    }
}

这对我有用 API 26 :

 navigation = (BottomNavigationView) view.findViewById(R.id.bottom_navigation);


     try{disableShiftMode(navigation);}catch(Exception ew){}

在您要调用的 Activity 或 Fragment 中制作此方法:

 @SuppressLint("RestrictedApi")
public static void disableShiftMode(BottomNavigationView view) {
    BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
    try {
        Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
        shiftingMode.setAccessible(true);
        shiftingMode.setBoolean(menuView, false);
        shiftingMode.setAccessible(false);
        for (int i = 0; i < menuView.getChildCount(); i++) {
            BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
            item.setShiftingMode(false);

            item.setChecked(item.getItemData().isChecked());
        }
    } catch (NoSuchFieldException e) {

    } catch (IllegalAccessException e) {

    }
}

您可以使用它在 BottomNevigationView 上同时显示 3 到 5 个项目的文本和图标并停止移动。

 app:labelVisibilityMode="labeled"

但是你会遇到BottmNevigationView 5 item的长文本切割问题。为此,我找到了一个很好的解决方案来停止移动文本以及 BottomNevigationView 的图标。您还可以停止移动 BottomNevigationView 上的文本和图标。此处提供代码截图。

1.在 BottomNevigationView 中添加这行代码,如图所示

<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="@dimen/seventy_dp"
    android:layout_semitransparent="true"
    android:background="@color/colorBottomNev"
    android:showAsAction="always|withText"
    app:itemIconTint="@drawable/bottom_navigation_colors"
    app:itemTextColor="@drawable/bottom_navigation_colors"
    app:itemTextAppearanceActive="@style/BottomNavigationViewTextStyle"
    app:itemTextAppearanceInactive="@style/BottomNavigationViewTextStyle"
    app:menu="@menu/bottom_navigation_menu"
    app:labelVisibilityMode="labeled"/>

2。添加如下菜单项:-

 <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_catalogue"
        android:icon="@drawable/catalogue"
        android:title="@string/catalogue"
        android:enabled="true"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/action_contracts"
        android:icon="@drawable/contract"
        android:title="@string/contracts"
        android:enabled="true"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/action_prospects"
        android:icon="@drawable/prospect"
        android:title="@string/prospects"
        android:enabled="true"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/action_performance"
        android:icon="@drawable/performance"
        android:title="@string/performance"
        android:enabled="true"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/action_advance"
        android:icon="@drawable/advance"
        android:title="@string/advance"
        android:enabled="true"
        app:showAsAction="ifRoom" />

</menu>

3.Add style.xml 文件中的这种样式:

 <style name="BottomNavigationViewTextStyle">
            <item name="android:fontFamily">@font/montmedium</item>
            <item name="android:textSize">10sp</item>
            <item name="android:duplicateParentState">true</item>
            <item name="android:ellipsize">end</item>
            <item name="android:maxLines">1</item>
        </style>

4)将这些添加到 Dimen 文件夹中

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <dimen name="design_bottom_navigation_text_size" tools:override="true">10sp</dimen>
    <dimen name="design_bottom_navigation_active_text_size" tools:override="true">10sp</dimen>
</resources>

我得到了这些link and link的帮助。你也可以通过学习这些得到帮助links.This对我有帮助lot.Hope这对你也有帮助。谢谢....

快速修复只需在 xml

中添加 app:labelVisibilityMode="labeled"
<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    app:itemBackground="@color/colorPrimary"
    app:itemIconTint="@drawable/bottom_navigation_color_selector"
    app:itemTextColor="@drawable/bottom_navigation_color_selector"
    app:labelVisibilityMode="labeled"
    app:menu="@menu/menu_bottom_navigation" />

备注

  implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'

有一点需要注意,尽管它不适用于这种情况。

当您有 3 到 5 个 top-level 个目的地要导航时,可以使用此模式。

要显示图标标题,请执行以下操作:

  1. 确保您的菜单 (bottom_navigation_menu) 项目 XML 结构如下:-

    <item
        android:id="@+id/action_home"
        android:enabled="true"
        android:icon="@drawable/ic_action_home"
        android:title="HOME"
        app:showAsAction="ifRoom"/>
    
    <item
        android:id="@+id/action_favourites"
        android:enabled="true"
        android:icon="@drawable/ic_action_favourite"
        android:title="FAVOURITES"
        app:showAsAction="ifRoom"/>
    
    <item
        android:id="@+id/action_basket"
        android:enabled="true"
        android:icon="@drawable/ic_action_basket"
        android:title="BASKET"
        app:showAsAction="ifRoom"/>
    

  2. 将以下内容添加到 BottomNavigationView 代码 app:labelVisibilityMode="labeled"

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:background="@android:color/white"
    app:itemIconTint="@android:color/black"
    app:itemTextColor="@android:color/black"
    app:menu="@menu/bottom_navigation_menu"
    app:labelVisibilityMode="labeled"/>

app:labelVisibilityMode="已标记"

Add above code under your XML file.

示例:

xmlns:app="http://schemas.android.com/apk/res-auto"


<com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav_view"
        ....
        ....
        app:labelVisibilityMode="labeled"/>