3つ以上のアイテムがあるBottomNavigationView:タブのタイトルが非表示になっている


85

Android Support Desing Library 25を使用してBottomNavigationViewを使用しています。しかし、タブを切り替えると、他のタブのタイトルが非表示になります。ただし、実際の下部ナビゲーションビューに隠れている問題はありません。しかし、私のものは隠れています。

MyBottomNavigation

でもそのようにしたいと思います。それをするためのアイデアはありますか?何が足りないのですか?

ActualBottomNavigation

これが私のコードです:

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>

app:showAsAction="always代わりに試しましたかifRoom
Yassine BELDI 2017年

試しましたが、まだ隠れています
Yunus Haznedar 2017年


1
@YunusHaznedar項目が3つ以上ある場合、テキストは常に非表示になります...
Shashankバーマ

1
ねえ、@ DanXPradoソリューションを共有してくれてありがとう。私はあなたの答えを受け入れ済みとしてマークしました。ハッピーコーディング。
Yunus Haznedar 2018年

回答:


143

フィールドmShiftingModeが削除されたため、リフレクションを使用したソリューションは機能しなくなりました。

今すぐ簡単に行う方法があります。サポートライブラリ28以降を使用app:labelVisibilityMode="labeled"し、BottomNavigationViewXML宣言に追加するだけです。

それが役に立てば幸い。


チャンピオンのように機能しますが、円形にスクロール可能にするにはどうすればよいですか?
Shailendra Madda 2018

@ShylendraMaddaこの質問とは関係がないので、新しい質問として投稿することをお勧めします。
ダニーロプラド

1
これはデフォルトの動作ではないのはなぜですか... app:showAsAction、android:visible、a​​ndroid:enabled、およびその他の多くのハックで数時間を無駄にしました。ありがとう!
デンマークのカーン

94

更新

サポートライブラリ28.0.0-alpha1のように、removeShiftMode()は不要になり、Labelsを追加できるようになりました。

XMLの場合:

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

プログラムで変更する場合:

mBottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); 

これを機能させるには:デザインサポートライブラリを28.0.0-alpha1に更新します

これが良い読み物です

古いサポートライブラリの場合:

あなた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'

BOTTOM NAVIGATIONVIEW 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);

タイトルテキストのシフトアニメーションを無効にし、テキストを表示できるようにします。


2
いいえ、まだ隠れています。「always」と「always | withText」を試しました
Yunus Haznedar 2017年

1
アイテムのタイトルの1つが大きいため、他のユーザーのビューがブロックされていますか?小さなタイトルと描画可能イメージでみてください...
rafsanahmad007

1
あなたがフォローしているtutotrialのこの行を参照してくださいIt’s important to note that the maximum number of items we can display is 5. This may change at any point, so it’s important to check this by using the getMaxItem() method provided by the BottomNavigationView class rather than hard-coding the value yourself.
rafsanahmad007 2017年

1
素晴らしい答え、ありがとう
ハムザアブドゥラ

2
リフレクションソリューションはでかなりうまく機能しcom.android.support:design:25.4.0ますがcom.android.support:design:26.1.0、で失敗するので、ターゲットSDKと依存関係のバージョンを少しロールバックします。
Evi Song

10

BottomNavigationViewのソースコードをスキャンした後、私は見つけました

mShiftingMode = mMenu.size() > 3;

BottomNavigationMenuView.javaのメニューのサイズが3以下、タブのタイトルを隠したことwiilながらライン265、それが意味しています。したがって、タブのタイトルを表示したい場合は、ビルドからコードを取得して以下に変更するだけです。

mShiftingMode = mMenu.size() > 5;

PS:BottonNavigationViewの最大タブ数は3から5の間でなければなりません。BottomNavigationViewNewでコードを取得できます ここに画像の説明を入力してください


BottomNavigationViewを拡張する独自のCustomBottomViewがありますが、代わりにそのプロパティを設定する方法はありますか?
JPM 2017

1
3タブの制限についての「BottomNavigationMenuView」の行が表示されません。たぶんコードが変更されましたか?
Androidデベロッパー

8

クラス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); 

1
それはrestrictAPIアナウンスの問題を解決するSuppressLintを持っています
code4j 2017

3

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")
    }
}

ありがとうございます。非常に感謝しています。
Yunus Haznedar 2018

1
item.setShiftingMode(false)現在item.setShifting(false)
Sim

2

私は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")
    }
}

1
この解決策はもはや有効ではありません。受け入れられた解決策は@DanXPradoによって正しいです
jpardogo

私に知らせてくれたThx–
Karma Maker

1

この場合は当てはまりませんが、注意が必要です。

このパターンは、ナビゲートするトップレベルの宛先が3〜5個ある場合に使用できます。

アイコンのタイトルを表示できるようにするには、次の手順を実行します。

  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コードアプリに以下を追加します: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"/>


0

これはAPI26で機能します:

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


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

呼び出したいアクティビティまたはフラグメントでこのメソッドを作成します。

 @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) {

    }
}

0

これを使用して、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>

私はこれらのリンクリンクから助けを得ました。これらの リンクを研究することによっても助けを得ることができます。これは私に大いに役立ちます。これがあなたにも役立つことを願っています。ありがとう....


0

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