如何禁用BottomNavigationView转换模式?

时间:2016-10-21 12:04:28

标签: android android-support-design bottomnavigationview

BottomNavigationView不会显示无效的菜单标题。

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

enter image description here

21 个答案:

答案 0 :(得分:312)

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指点this issueproviding snippet

更新2

正如Jolanda Verhoef所指出的那样,新的支持库(28.0.0-alpha1)以及新的Material Components library1.0.0-beta01)提供了一个公共属性,可以用来操纵3的转换模式菜单项。

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

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

更新3

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

您可以查看BottomNavigation here

样式的完整指南

答案 1 :(得分:38)

自支持库 28.0.0-alpha1:

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

答案 2 :(得分:22)

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

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

您可能还需要在清单中添加它:

tools:override="true"

答案 3 :(得分:17)

您现在可以在class Author(models.Model): Firtname = models.CharField(max_length=50) middlename = models.CharField(max_length=50, null=True, blank=True) secondsurname = models.CharField(max_length=30) lastName = models.CharField(max_length=30) def __str__(self): return '{lname} {sname} {fname}'.format( lname=self.lastName or '', sname=self.secondsurname or '', fname=self.Firtname or '' ) def __unicode__(self): return smart_unicode(str(self))

中使用app:labelVisibilityMode="[labeled, unlabeled, selected, auto]"
  • 28-alpha 会保留所有标签。
  • labeled 只会显示图标。
  • unlabeled 只会显示所选商品的标签和商品。
  • selected 会根据您拥有的商品数量选择标记或选择。标记为1-3项,并为3项以上项目选择。

答案 4 :(得分:16)

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 Extensions):

bottom_navigation_view.disableShiftMode()

答案 5 :(得分:9)

为我工作

bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

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

答案 6 :(得分:9)

要禁用文本动画并减小字体大小,请在dimens.xml文件中使用:

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

答案 7 :(得分:5)

正如其他人指出的那样,自支持库28.0.0-alpha1 以来,就有可能:

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

或者您可以将其设置为programatically

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

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

如果您使用Gradle

  1. 您可以通过以下方式检查您的透支 运行 dependencies 任务并搜索 com.android.support:design 的版本号。
  2. 要在您的 build.gradle 中明确添加设计支持依赖项:

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

答案 8 :(得分:4)

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

  

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

并放入您的BottomNavigationView xml属性

app:itemHorizontalTranslationEnabled="false"

您也可以以编程方式放置它

bottomNavigationView.setItemHorizontalTranslationEnabled(false);

您可以在这里BottomNavigationView

找到源

希望这对您有所帮助。

答案 9 :(得分:4)

更新

在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());
        }
    }
}

答案 10 :(得分:2)

这是我使用的第三方库,它有许多自定义选项,例如禁用shift模式,仅显示图标,设置图标大小等。 BottomNavigationViewEx

答案 11 :(得分: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;
}

答案 12 :(得分:2)

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

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

android:fitsSystemWindows="true"

在片段的根布局中。只需删除它和繁荣! BottomNavigationView可以正常工作,现在它可以显示文本和图标。 我在片段的根CoordinatorLayout中有这个。

也不要忘记添加

BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

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

答案 13 :(得分:2)

在您的 BottomNavigationView 中添加app: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 Bottom Navigation View Disable Text and Shift

答案 14 :(得分:1)

如果您使用的是support:design:28.0.0,请将此行app:labelVisibilityMode =“ unlabeled”添加到您的BottomNavigationView

答案 15 :(得分:0)

只想添加上面的方法disableShiftMode也添加下面的代码。 @SuppressLint(&#34; RestrictedApi&#34)

答案 16 :(得分:0)

将支持库更新为28.0.0。

bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

答案 17 :(得分:0)

这很简单,只需在BottomNaviationView中添加一个属性

app:labelVisibilityMode="unlabeled"

答案 18 :(得分: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>

答案 19 :(得分:0)

我使用Android Studio 4.0.1进行开发。 以下是我的结果... enter image description here

关于BottomNavigationViewHelper.java 我的代码在这里工作

3.7

然后我们可以开始使用BottomNavigationViewHelper类 这是我的MainActivity.java代码。

BottomNavigationView navView = findViewById(R.id.nav_view); BottomNavigationViewHelper.disableShiftMode(navView);

3.6

答案 20 :(得分:-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>

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