BottomNavigationViewシフトモードを無効にする方法


146

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

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

ここに画像の説明を入力してください



あなたがしたい場合はここで便利な答えだ完全に任意のアニメーションを削除します。stackoverflow.com/a/51052247/2352699
フレッドPorciúncula

回答:


330

の実装に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

更新

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

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

指してくれてありがとうムハンマドAlfaifi この問題をスニペットを提供します

アップデート2

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

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

Material Componentsライブラリでは、5つのメニュー項目がある場合にも適用されます。

アップデート3

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

ここで BottomNavigationのスタイル設定の完全なガイドを確認できます


10
****プロガード:(
Muhammad Alfaifi 2016

17
フィールドは難読化されるため、proguard-rulesファイルで除外しない限り、値を変更する方法はありません
Muhammad Alfaifi

8
-keepclassmembers class android.support.design.internal.BottomNavigationMenuView {boolean mShiftingMode; }
Muhammad Alfaifi 16

8
ときどき、なぜGoogleが開発者にビューの実装を強制するのか、本当に不思議に思うことがあります。Google+アプリ自体には4つのオプションがありますが、このシンプルな機能は、可能であればシンプルな関数を介してアクセスできるはずです!同様の問題がTabLayoutにもありましたが、サポートライブラリで後でかなり修正されました。これを改善してくれたOriginal Replierと@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 2018

1
正常に動作しています。熟考する必要はありません。おかげで
ブペシュ2018

1
@ライザーは使用してapp:いないことを確認してくださいandroid:
カーソンホルツハイマー

28

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

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

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

tools:override="true"

機能していません。これを/values/dimens.xmlに追加する必要があると思いますか?
Rohan Kandwal 2017年

10
@RohanKandwalが追加する必要があるtools:override="true"
Boy

@男の子ありがとう、試してみます。
Rohan Kandwal 2017年

文字サイズのみを変更します。
デュード

私はちょうど私のdimens.xmlファイルに次のように配置する必要があります:<dimen name="design_bottom_navigation_active_text_size" tools:ignore="PrivateResource">12sp</dimen>
フェルナンド・バルボサ

22

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

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

1
ランキー、ありがとう!これは私にとって最良かつ最も簡単なソリューションです
Gregriggins36

このコード行を追加する場所。追加しようとしましたが、見つからないエラーがあります。
Abdulwahid

@Abdulwahidサポートライブラリが28以上の場合は、下部のナビゲーションバーのxmlにこれを追加できます
Aidan Laing

@Lunkieのおかげで、サポートライブラリ28
Abdulwahidが

17

拡張関数としての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()

コトリンのために働いています。なぜこのアノテーション@SuppressLint( "RestrictedApi")を使用する必要があるのですか?plsについて説明できますか?
Ranjith Kumar

11

私のために働く

bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

または

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

私はtarget = 27までは問題なく動作していましたが、target = 28以降は壊れており、テキストは表示されなくなりました。しかし、setLabelVisibilityModeは私にとってはトリックであり、今では魅力のように機能します
joke4me

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 2017年

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")楽しいremoveShiftMode(ビュー:BottomNavigationView){ヴァルmenuView = view.getChildAt(0)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. Depdendeciesを確認するには、依存関係タスクを実行し、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は、テキスト付きのアイコンを表示するか、選択時にアイコンのみを表示するかを表示するためのものです。
レスターL.

3

あなたの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の下部ナビゲーションビューでテキストとシフトを無効にする


3

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

app:labelVisibilityMode="unlabeled"

2

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

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

android:fitsSystemWindows="true"

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

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

BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

あなたの活動でシフトモードを無効にします。質問とは正確には関係ありませんが、それでも役に立ちます。


1
@ abbath0767 リンクを見たことがありますか?あなたに役立つかもしれません。
Kishan Solanki 2018年

私はすでにすべてを試したことがあると思いました、ありがとうございました、私が求めていた答えを直接見つけることを期待していませんでした。
BekaBot

1
喜び@BekaBot
Kishan

2

これは私が使用するサードパーティのライブラリであり、シフトモードの無効化、アイコンのみの表示、アイコンサイズの設定など、多くのカスタマイズオプションがあります 。BottomNavigationViewEx


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

そして、それを必ずプロガード設定ファイルに追加してください:

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

28.ターゲットあればアンドロイド9(APIレベル28)は非SDKインタフェースを使用して、このないだろう作品に新たな規制を導入し developer.android.com/about/versions/pie/...を
ernestkamara

2

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

bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

1

support:design:28.0.0を使用している場合は、この行app:labelVisibilityMode = "unlabeled"をBottomNavigationViewに追加します


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"/>

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

しかし、5つの項目についてBottmNevigationViewで長いテキストがカットされる問題に直面します。そのため、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>

私はこれらのリンクリンクから助けを得ました。これらの リンクを研究することで助けを得ることもできます。これは私に多くの助けになります。ありがとう...

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