web-dev-qa-db-ja.com

BottomNavigationViewシフトモードを無効にするには?

BottomNavigationViewは、アクティブでないメニューのタイトルを表示しません。

BottomNavigationBarにすべてのメニュー要素のタイトルを表示する方法は?問題は、私の場合はクリックされた要素のタイトルだけが表示されることです。

enter image description here

129

BottomNavigationViewの実装には条件があります:3つ以上のアイテムがある場合、シフトモードを使用します。

現時点では、既存のAPIを使用して変更することはできません。シフトモードを無効にする唯一の方法は、リフレクションを使用することです。

ヘルパークラスが必要です。

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のメニュー項目を変更するたびに、このメソッドを実行する必要があることに注意してください。

UPDATE

また、proguard構成ファイル(例:proguard-rules.pro)を更新する必要があります。上記のコードはリフレクションを使用し、proguardがmShiftingModeフィールドを難読化すると機能しません。

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

この問題スニペットの提供 を指し示してくれたMuhammad Alfaifiに感謝します。

更新2

Jolanda Verhoefが新しいサポートライブラリ(28.0.0-alpha1)と新しい Material Componentsライブラリ1.0.0-beta01)を指摘したように、シフトモードを操作するために使用できるパブリックプロパティを提供します3つ以上のメニュー項目。

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

マテリアルコンポーネントライブラリでは、5つのメニュー項目がある場合にも適用されます。

更新3

@ThomasSunderlandも指摘したように、このプロパティをfalseに設定すると、Enabled接尾辞なしでapp:itemHorizontalTranslation="false"を設定して、アニメーションのシフトを無効にできます。

bottomNavigationのスタイリングに関する完全なガイドを確認できます here

サポートライブラリより28.0.0-alpha1:

<Android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />
39
Junbin Deng

テキストアニメーションを無効にするには、これをdimens.xmlファイルで使用することもできます。

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

マニフェストにこれを追加する必要があるかもしれません。

tools:override="true"
22
Pafoid

app:labelVisibilityMode="[labeled, unlabeled, selected, auto]"28-alphaを使えるようになりました

  • labeledはすべてのラベルを表示したままにします。
  • unlabeledはアイコンだけを表示します。
  • selectedは選択されたアイテムとシフトアイテムのラベルのみを表示します。
  • autoはあなたが持っているアイテムの数に基づいてラベル付きか選択されたものを選びます。 1〜3項目にラベルを付け、3項目以上に選択します。
17
Aidan Laing

拡張機能としてのKotlinでのPrzemysławの答え

@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()
16
ElegyD

テキストアニメーションを無効にしてフォントサイズを小さくするには、dimens.xmlファイルでこれを使用します。

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

私のために働く

bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

または

<Android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />
9
UgAr0FF

他の人が指摘したように、はライブラリ28.0.0-alpha1をサポートしているので可能です:

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

またはプログラム的に設定 することもできます

注:古いバージョンのサポートライブラリからアップグレードする場合は、コンパイルSDKのバージョンを上げることを忘れないでください。サポートライブラリのバージョンをここで確認してください。 サポートライブラリのバージョン

ただし、アプリケーションが以前のバージョンのデザインサポートライブラリに依存している場合は、コンパイル時にlabelVisibilityModeが見つかりませんというメッセージが表示されることがあります。その場合は、少なくとも設計サポートライブラリのバージョン28.0.0-alpha1に依存する、指定された依存関係のバージョンにアップグレードしてみてください。それが不可能な場合は、依存関係を明示的に定義してください。

Gradleを使うなら

  1. あなたは依存関係タスクを実行してcom.Android.support:designのバージョン番号を検索することによってあなたの依存関係をチェックすることができます。
  2. あなたのbuild.gradleで明示的に設計サポートの依存関係を追加するには:

    実装 'com.Android.support:design:28.0.0'

5

デフォルトを使用して回答を更新しました。最新のデザインライブラリに更新する

実装 "com.Android.support:design:28.0.0"

そしてあなたのBottomNavigationView xml属性に置く

app:itemHorizontalTranslationEnabled="false"

プログラム的にも置くことができます

bottomNavigationView.setItemHorizontalTranslationEnabled(false);

あなたはここでソースを見つけることができます BottomNavigationView

これがお役に立てば幸いです。

4
Lester L.

更新

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

あなたの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 Bottom Navigation View Disable Text and Shift

2

私はBottomNavigationViewでいくつかの奇妙な振る舞いをしました。その中の任意のアイテム/フラグメントを選択していたときに、フラグメントはBottomNavigationViewを少し下にプッシュします。そのため、BottomNavigationViewのテキストは画面の下に表示されます。

あなたがその奇妙なふるまいに直面しているなら、それからこれが解決策です。削除するだけ

Android:fitsSystemWindows="true"

フラグメントのルートレイアウトに。これを外してブームしてください。 BottomNavigationViewは問題なく動作しますが、テキストとアイコンで表示できるようになりました。私はこれをフラグメントのルートCoordinatorLayoutに持っていました。

また追加することを忘れないでください

BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

あなたの活動の中でシフトモードを無効にする。それは尋ねられた質問と正確には関連していませんが、それでも私はこれが役に立ちます。

2

これは私が使っているサードパーティのライブラリで、シフトモードを無効にしたり、アイコンだけを表示したり、アイコンのサイズを設定したりなど、カスタマイズオプションがたくさんあります。 BottomNavigationViewEx

2
Pei

アニメーションを完全に削除するには:

あなたもその迷惑な小さな上マージンアニメーションを取り除きたい場合は、より多くの反射コードが必要です。アニメーションを削除する完全な解決策は次のとおりです。

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

サポートライブラリを28.0.0に更新します。

bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
1
M Moersalin

あなたがサポートを使用しているならば:デザイン:28.0.0あなたのBottomNavigationViewにこの行アプリを追加します:labelVisibilityMode = "unlabeled"

1
Omar Hassan

とても簡単です。BottomNaviationViewにプロパティを追加するだけです

app:labelVisibilityMode="unlabeled"
1
Nevil Ghelani

このメソッドに上記のdisableShiftModeコードを追加してください。 @SuppressLint( "RestrictedApi")

0
Aleesha Kanwal