如何禁用BottomNavigationView移位模式?


146

BottomNavigationView不会显示未激活的菜单标题。

如何在bottomNavigationBar中显示所有菜单元素的标题?问题是在我的情况下,仅显示被单击元素的标题。

在此处输入图片说明



如果您想完全删除任何动画,这是一个有用的答案:stackoverflow.com/a/51052247/2352699
FredPorciúncula18年

Answers:


330

BottomNavigationView有条件的实现:当有3个以上的项目时,使用班次模式。

目前,您无法通过现有的API对其进行更改,并且禁用shift模式的唯一方法是使用反射。

您将需要帮助程序类:

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 {
    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);
                //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);
        }
    }
}

然后disableShiftMode在上应用方法BottomNavigationView,但请记住,如果要从代码中扩展菜单视图,则必须在扩展后执行它。

用法示例:

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

PS。

请记住,每次更改中的菜单项时,都需要执行此方法BottomNavigationView

更新

您还需要更新proguard配置文件(例如proguard-rules.pro),上面的代码使用反射,如果proguard混淆了该mShiftingMode字段,则该代码将不起作用。

-keepclassmembers class android.support.design.internal.BottomNavigationMenuView { 
    boolean mShiftingMode; 
}

感谢Muhammad Alfaifi指出了这个问题提供了摘要。

更新2

正如Jolanda Verhoef指出的那样,新的支持库(28.0.0-alpha1)和新的材料组件库1.0.0-beta01)提供了一个公共属性,可用于操纵3个菜单项上的切换模式。

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

在Material Components库中,如果有5个菜单项,则也适用。

更新3

正如@ThomasSunderland也指出的那样,您可以将此属性设置为false,app:itemHorizontalTranslation="false"而无需使用Enabled后缀来禁用移动动画。

您可以在此处查看有关BottomNavigation样式的完整指南


10
**** Proguard :(
穆罕默德·阿尔法菲

17
该字段将被混淆,因此除非您将其排除在proguard-rules文件中,否则无法更改其值
Muhammad Alfaifi

8
-keepclassmembers类android.support.design.internal.BottomNavigationMenuView {boolean mShiftingMode; }
穆罕默德·阿尔法菲

8
有时候,我真的很奇怪,为什么Google会强制在开发人员身上查看实现。虽然Google+应用程序本身有4个选项,但应该可以通过简单功能访问此简单功能!TabLayout也存在类似问题,该问题后来在支持库中得到了修复。感谢您对原始复制者和@MuhammadAlfaifi的解决方法,以改善此问题。
sud007

19
新的支持库(28.0.0-alpha1)支持通过app:labelVisibilityMode =“ labeled”更改此行为
Jolanda Verhoef

50

从支持库28.0.0-alpha1开始:

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

1
我正在使用此支持库版本,但仍找不到“ labelVisibilityMode”错误。
Sagar Maiyad '18

1
好好工作。无需反思。感谢吨
布达佩斯

1
@Riser确保您使用的app:不是android:
卡森Holzheimer

28

要禁用文本动画,您还可以在dimens.xml文件中使用此动画:

<dimen name="design_bottom_navigation_active_text_size">12sp</dimen>

您可能还需要在清单中添加以下内容:

tools:override="true"

不工作。我相信我只需要在/values/dimens.xml中添加它?
罗汉·坎德瓦尔

10
@RohanKandwal需要添加tools:override="true"
男孩子

@男孩谢谢,将尝试。
Rohan Kandwal '17

仅更改文字大小。
花花公子

我只需要这样在我的dimens.xml文件中放:<dimen name="design_bottom_navigation_active_text_size" tools:ignore="PrivateResource">12sp</dimen>
Fernando Barbosa

22

您现在可以app:labelVisibilityMode="[labeled, unlabeled, selected, auto]"28-alpha

  • labeled 将保持所有标签可见。
  • unlabeled 将仅显示图标。
  • selected 将仅显示所选项目和班次项目的标签。
  • auto将根据您拥有的商品数量选择带标签或已选择。标记为1-3项,选择为3+项。

1
谢谢伦基!对我来说,这是最好,最简单的解决方案
Gregriggins18年

在哪里添加此行代码。我尝试添加,但是找不到错误。
阿卜杜勒瓦希德'18

@Abdulwahid,一旦您具有支持库28或更高版本,就可以在底部导航栏的xml中添加它
Aidan Laing

@Lunkie现在非常感谢,一旦支持库28
Abdulwahid

17

Przemysław在Kotlin中的答案是扩展功能

@SuppressLint("RestrictedApi")
fun BottomNavigationView.disableShiftMode() {
    val menuView = getChildAt(0) as BottomNavigationMenuView
    try {
        val shiftingMode = menuView::class.java.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) {
        Log.e(TAG, "Unable to get shift mode field", e)
    } catch (e: IllegalStateException) {
        Log.e(TAG, "Unable to change value of shift mode", e)
    }
}

用法(与Kotlin Android扩展一起使用):

bottom_navigation_view.disableShiftMode()

在科特林工作。为什么我们需要使用此注释@SuppressLint(“ RestrictedApi”)您可以解释一下吗?
Ranjith Kumar

11

为我工作

bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

要么

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

我的工作正常,直到target = 27,但是从target = 28起,它坏了,不再显示文本。但是setLabelVisibilityMode帮了我
大忙

10

要禁用文本动画并减小字体大小,请在您的dimens.xml文件中使用以下命令:

<dimen name="design_bottom_navigation_text_size">10sp</dimen> 
<dimen name="design_bottom_navigation_active_text_size">10sp</dimen>

人们可以Navigate- > File...> design_bottom_navigation_item.xml一看就知道有没有其他办法。
arekolek

6

更新

在Android SDK版本28及更高版本中,它们已更改item.setShiftingMode(false)item.setShifting(false)

他们也删除了领域 mShiftingMode

因此用法将是

 BottomNavigationHelper.removeShiftMode(bottomNav);
 bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);


 private static final class BottomNavigationHelper {
    @SuppressLint("RestrictedApi")
    static void removeShiftMode(BottomNavigationView view) {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        for (int i = 0; i < menuView.getChildCount(); i++) {
            BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
            //noinspection RestrictedApi
            item.setShifting(false);
            item.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

            // set once again checked value, so view will be updated
            //noinspection RestrictedApi
            item.setChecked(item.getItemData().isChecked());
        }
    }
}

您可以在下面使用此代码。@SuppressLint(“ RestrictedApi”)fun removeShiftMode(view:BottomNavigationView){val menuView = view.getChildAt(0)as BottomNavigationMenuView menuView.labelVisibilityMode = LabelVisibilityMode.LABEL_VISIBILITY_LABELED menuView.buildMenuView()}
深P

5

正如其他人指出的那样,由于支持库28.0.0-alpha1,因此可能:

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

或者您可以通过编程设置它。

注意:如果要从较旧版本的支持库升级,请不要忘记提高编译SDK版本。在此处检查支持libraray的版本支持库版本

但是,如果您的应用程序依赖于设计支持库的较早版本,则在编译时仍然可能会收到labelVisibilityMode not found消息。如果是这种情况,请尝试升级到给定依赖性的版本,该依赖性至少取决于设计支持库的28.0.0-alpha1版本。如果不可能,请显式定义依赖项。

如果您使用Gradle

  1. 您可以通过运行依赖项任务并搜索com.android.support:design的版本号来检查您的依赖关系
  2. 要在build.gradle中显式添加设计支持依赖性:

    实施'com.android.support:design:28.0.0'


4

对于使用默认值的更新答案。更新到最新的设计库

实现“ com.android.support:design:28.0.0”

并放入您的BottomNavigationView xml属性

app:itemHorizontalTranslationEnabled="false"

您也可以以编程方式

bottomNavigationView.setItemHorizontalTranslationEnabled(false);

您可以在此处找到源代码BottomNavigationView

希望对您有帮助。


这有什么不同app:labelVisibilityMode
wonsuc

@wonsuc这是关于所选项目正在制作动画的图标和文本的动画。而labelVisibilityMode用于显示是要显示带有文本的图标,还是仅显示要在选择时显示的图标。
Lester L.19年

3

给你BottomNavigationViewapp:labelVisibilityMode="unlabeled"

<android.support.design.widget.BottomNavigationView
        app:menu="@menu/bn_menu"
        android:layout_height="56dp"
        android:layout_width="match_parent"
        app:labelVisibilityMode="unlabeled">

</android.support.design.widget.BottomNavigationView>

结果如下

Android底部导航视图禁用文本和移位



2

我在BottomNavigationView上有一些奇怪的行为。当我在其中选择任何项目/片段时,该片段将BottomNavigationView推低一点,因此BottomNavigationView的文本位于屏幕下方,因此单击任何项​​目时仅可见图标并且隐藏文本。

如果您面对这种奇怪的行为,那么这就是解决方案。只需删除

android:fitsSystemWindows="true"

在片段的根布局中。只需移除此杆即可!BottomNavigationView可以正常工作,现在可以用文本和图标显示。我在片段的根CoordinatorLayout中有此选项。

也不要忘记添加

BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

在您的活动中禁用换档模式。尽管它与提出的问题并不完全相关,但我仍然认为这很有帮助。


1
@ abbath0767您看到链接了吗?可能对您有帮助。
基尚

我以为我已经尝试了一切,非常感谢,没想到直接找到我想要的答案。
BekaBot

1
@BekaBot的快乐
Kishan Solanki,


2

要完全删除动画:

如果您还想摆脱那种烦人的小顶边动画,则需要更多的反射代码。这是删除所有动画的完整解决方案:

@SuppressLint("RestrictedApi")
private 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);

            Field shiftAmount = item.getClass().getDeclaredField("mShiftAmount");
            shiftAmount.setAccessible(true);
            shiftAmount.setInt(item, 0);
            shiftAmount.setAccessible(false);

            item.setChecked(item.getItemData().isChecked());
        }
    } catch (NoSuchFieldException e) {
        Timber.e(e, "Unable to get fields");
    } catch (IllegalAccessException e) {
        Timber.e(e, "Unable to change values");
    }
}

并确保将其添加到您的proguard配置文件中:

-keepclassmembers class android.support.design.internal.BottomNavigationMenuView { 
    boolean mShiftingMode; 
}
-keepclassmembers class android.support.design.internal.BottomNavigationItemView { 
    int mShiftAmount;
}

Android的9(API 28级)上使用的非SDK接口引入了新的限制,这是行不通的,如果针对28 developer.android.com/about/versions/pie/...
ernestkamara

2

将支持库更新为28.0.0。

bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);


0

只是想在此方法之上添加disableShiftMode也在代码下方添加。@SuppressLint(“ RestrictedApi”)


0

https://android.jlelse.eu/disable-shift-label-animation-from-bottom-navigation-android-b42a25dcbffc

1个

<com.google.android.material.bottomnavigation.BottomNavigationView
...
app:itemHorizontalTranslationEnabled="false"/>

2

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

3

<resources xmlns:tools="http://schemas.android.com/tools">
<dimen name="design_bottom_navigation_active_text_size"
    tools:override="true">12sp</dimen>


-1

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

 app:labelVisibilityMode="labeled"

但是您将在BottmNevigationView上遇到5个项目的长文本切割问题。为此,我找到了一个很好的解决方案,可以停止文本以及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.在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>

我从这些 链接链接中获得帮助。您也可以通过研究这些链接来获得帮助。这对我有很大帮助。希望这也对您有所帮助。谢谢....

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.