BottomNavigationViewは常にアイコンとテキストラベルの両方を表示します


125

設計サポートライブラリバージョン25のandroid.support.design.widget.BottomNavigationViewを使用しています

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

<android.support.design.widget.BottomNavigationView
        android:id="@+id/bottomBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="center"
        app:itemBackground="@color/colorPrimary"
        app:menu="@menu/bottom_navigation_main"
        android:forceHasOverlappingRendering="true"/>

@ menu / bottom_navigation_mainに3つのアクションしかない場合は、アイコンとテキストラベルの両方が常に表示されます。

4つ以上のアクションがあるときに、アイコンとテキストラベルの両方を常に表示する方法は何ですか。


bottom_navigation_main.xmlメニューで、android:showAsAction = "ifRoom"がある場合は、アイテムごとにandroid:showAsAction = "always"に変更します。
Shashank Udupa 2016年

いいえ、機能しませんでした。以前に試したことがある。
Androidデベロッパー

メニューのxmlファイルを表示できますか
Shashank Udupa 2016年

'<?xml version = "1.0" encoding = "utf-8"?> <menu xmlns:android = " schemas.android.com/apk/res/android " xmlns:app = " schemas.android.com/apk/ res-auto "> <item android:id =" @ + id / action_favorites "app:showAsAction =" always "/> <item android:id =" @ + id / action_schedules "app:showAsAction =" always "/> < item android:id = "@ + id / action_music" app:showAsAction = "always" /> <item android:id = "@ + id / account" android:enabled = "true" app:showAsAction = "always" /> </ menu> '
Androidデベロッパー

4
app:labelVisibilityMode = "labeled"をBottomNavigationViewに配置します。
シュラワン

回答:


325

まだソリューションを探していて、サードパーティのライブラリやランタイムリフレクションに依存したくない場合は、Support Library 28 / JetpackのBottomNavigationViewが常にテキストラベルを持つことをネイティブでサポートします。

これはあなたが探している方法です。

またはXMLで、 app:labelVisibilityMode="labeled"


どのライブラリバージョンが必要ですか?
DaniloDeQueiroz

サポートライブラリ28-alpha1 +
shaishgandhi

表示モードを「自動」に変更して、押された/フォーカスされたときにのみアイコンテキストを表示することもできます。コード:app:labelVisibilityMode = "auto"
Kenny Dabiri

あなたは男です!マテリアルライブラリの最新バージョンで動作します。ありがとうございます。
sud007

68

2018年5月8日からの更新

app:labelVisibilityMode="labeled" 直接使用できます <android.support.design.widget.BottomNavigationView />

ソース:https : //developer.android.com/reference/com/google/android/material/bottomnavigation/LabelVisibilityMode

以下の長いソリューションではこれは必要ありません。

以前の回答

BottomNavigationViewで奇妙な動作がありました。その中のアイテム/フラグメントを選択していたとき、フラグメントはBottomNavigationViewを少し下にプッシュするため、BottomNavigationViewのテキストは画面の下に表示されるため、アイコンのみが表示され、アイテムをクリックするとテキストが非表示になります。

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

android:fitsSystemWindows="true"

フラグメントのルートレイアウト。これを外してブームだけ!BottomNavigationViewは正常に動作し、テキストとアイコンで表示できるようになりました。これはフラグメントのルートCoordinatorLayoutにありました。

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

BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);

あなたの活動でシフトモードを無効にします。

ここにそのクラスがあります:

public class BottomNavigationViewHelper {

    @SuppressLint("RestrictedApi")
    public static void removeShiftMode(BottomNavigationView view) {
        //this will remove shift mode for bottom navigation 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);
                // set once again checked value, so view will be updated
                item.setChecked(item.getItemData().isChecked());
            }

        } catch (NoSuchFieldException e) {
            Log.e("ERROR NO SUCH FIELD", "Unable to get shift mode field");
        } catch (IllegalAccessException e) {
            Log.e("ERROR ILLEGAL ALG", "Unable to change value of shift mode");
        }
    }
}

これをSTAR_ZEROの回答と組み合わせると、私の問題は解決しました!
クリストファースミット

あなたが持っているコールでdisableShiftMode、そしてクラスでremoveShiftMode。その少しの矛盾を除いて、あなたの答えは私のために問題を解決しました。シフトなしで、テキスト+アイコン付きの5つのメニュー項目があります。ありがとう非常に多くの!
ヤマズレ

完璧です。下のナビゲーションに3つ以上のアイテムがある場合、シフトモードが表示されます。これを使用すると、そのシフトを無効にできるため、テキスト付きのすべてのアイコンが一度に表示されます。
Kishor Bikram Oli

1
これは無制限のAPIであり、サポートライブラリバージョン28以降では機能しません。受け入れられた@shaishgandhiの答えは、より適切な方法です。
カラコセ2018

19

バージョン25では難しいです。

このコードを試してください。しかし、それは良い解決策ではないと思います。

BottomNavigationView navigationView = (BottomNavigationView) findViewById(R.id.bottomBar);
BottomNavigationMenuView menuView = (BottomNavigationMenuView) navigationView.getChildAt(0);
for (int i = 0; i < menuView.getChildCount(); i++) {
    BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(i);
    itemView.setShiftingMode(false);
    itemView.setChecked(false);
}

Android Studioでは、次のようなコードを追加する必要があります: `` `// noinspection RestrictedApi itemView.setShiftingMode(false); // noinspection RestrictedApi itemView.setChecked(false); `` `
Jiezhi.G 2017

4
それでもシフトアイテムです
CodeToLife 2017年

1
パーフェクト!! アイコンとテキストの両方を表示します。しかし、シフトモード(false)は機能しません。
Minkoo 2017

これをKishanSolanki124の回答と組み合わせると、私の問題は解決しました!
Christopher Smit

11

@STAR_ZEROと@ KishanSolanki124のソリューションを組み合わせたKotlin拡張関数を次に示します。

fun BottomNavigationView.disableShiftMode() {
    val menuView = getChildAt(0) as BottomNavigationMenuView

    menuView.javaClass.getDeclaredField("mShiftingMode").apply {
        isAccessible = true
        setBoolean(menuView, false)
        isAccessible = false
    }

    @SuppressLint("RestrictedApi")
    for (i in 0 until menuView.childCount) {
        (menuView.getChildAt(i) as BottomNavigationItemView).apply {
            setShiftingMode(false)
            setChecked(false)
        }
    }
}

それを使用するには:

myBottomNavigation.disableShiftMode()

10

この効果をしたいですか?

ここをクリックして画像を表示

その場合は、BottomNavigationViewExを試すことをお勧めします。


1
あなたのライブラリは優れた印象的な作品ですが、デザインライブラリ25.0.0を使用してこの機能を実現しようとしていましたが、残念ながら
Androidの

docsの「Fixed bottom navigation bar」によると、これはマテリアルデザインの仕様に反するものではありません。また、この素晴らしいライブラリを共有してくれた個人的な感謝です。
Serg de Adelantado 2017年

1
これはマテリアルデザインの仕様に反しています。提供したドキュメントを読むと、「4つまたは5つのアクションがある場合、非アクティブなビューをアイコンとしてのみ表示する」と明示されていることがわかります。
フェリペ

8

これを使用して、BottomNevigationViewにテキストとアイコンの両方を表示できます。

app:labelVisibilityMode="labeled"

これを使用している場合は、アイコンとテキストの両方を表示できます

<android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/bottom_navigation_view"
    android:layout_alignParentBottom="true"
    app:menu="@menu/bottom_navigation_menu"/>

6

app:labelVisibilityMode = "labeled"を直接使用できます

<com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:labelVisibilityMode="labeled"
        android:elevation="8dp"
        android:layout_alignParentBottom="true"
        app:itemBackground="@drawable/bottom_navi"
        app:itemTextColor="@color/white"
        app:itemIconTint="@color/white"
        app:menu="@menu/bottom_nav_menu_managment" />

5

BottomNavigationViewクラスにはBottomNavigationMenuViewフィールドがあり、BottomNavigationMenuViewにはBottomNavigationItemView []フィールドがあり、これは下部のバーのアイテムです。

nはアイテムの数であり、BottomNavigationMenuViewはBottomNavigationItemView []配列の各メンバーでBottomNavigationItemView.setShiftingMode(n> 3)を呼び出します。この関数は動作を決定します(タイトルを常に表示するか、選択したときにのみ表示します)。

したがって、常にタイトルを表示する方法は、このメソッドを呼び出すことです。リフレクションを使用してプライベートフィールドにアクセスできます。

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


//  get the private BottomNavigationMenuView field 
        Field f = null;
        try {
            f = bottomNavigationView.getClass().getDeclaredField("mMenuView");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        f.setAccessible(true);
        BottomNavigationMenuView menuView=null;
        try {
             menuView = (BottomNavigationMenuView) f.get(bottomNavigationView); 
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

//  get the private BottomNavigationItemView[]  field 
        try {
            f=menuView.getClass().getDeclaredField("mButtons");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        f.setAccessible(true);
        BottomNavigationItemView[] mButtons=null;
        try {
            mButtons = (BottomNavigationItemView[]) f.get(menuView); 
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


        for(int i=0;i<mButtons.length;i++){
            mButtons[i].setShiftingMode(false);
            mButtons[i].setChecked(true);
        }

これは非常に優れています。BottomNavigationMenuViewもシフトしないようにする必要があるだけです。-> f = menuView.getClass()。getDeclaredField( "mShiftingMode"); f.setAccessible(true); f.setBoolean(menuView、false);
ステファンk。

4

タイトルをずっと表示するため。次のKotlinコードを試してください:

@SuppressLint("RestrictedApi")
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_ofree)

    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)

    val menuView = navigation.getChildAt(0) as BottomNavigationMenuView
    for (i in 0 until menuView.childCount) {
        val itemView = menuView.getChildAt(i) as BottomNavigationItemView
        itemView.setShiftingMode(false)
        itemView.setChecked(false)
    }
}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.