BottomNavigationViewは、アクティブでないメニューのタイトルを表示しません。
BottomNavigationBarにすべてのメニュー要素のタイトルを表示する方法は?問題は、私の場合はクリックされた要素のタイトルだけが表示されることです。
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" />
テキストアニメーションを無効にするには、これをdimens.xmlファイルで使用することもできます。
<dimen name="design_bottom_navigation_active_text_size">12sp</dimen>
マニフェストにこれを追加する必要があるかもしれません。
tools:override="true"
app:labelVisibilityMode="[labeled, unlabeled, selected, auto]"
で28-alpha
を使えるようになりました
labeled
はすべてのラベルを表示したままにします。unlabeled
はアイコンだけを表示します。selected
は選択されたアイテムとシフトアイテムのラベルのみを表示します。auto
はあなたが持っているアイテムの数に基づいてラベル付きか選択されたものを選びます。 1〜3項目にラベルを付け、3項目以上に選択します。拡張機能としての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()
テキストアニメーションを無効にしてフォントサイズを小さくするには、dimens.xmlファイルでこれを使用します。
<dimen name="design_bottom_navigation_text_size">10sp</dimen>
<dimen name="design_bottom_navigation_active_text_size">10sp</dimen>
私のために働く
bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
または
<Android.support.design.widget.BottomNavigationView
app:labelVisibilityMode="labeled" />
他の人が指摘したように、はライブラリ28.0.0-alpha1をサポートしているので可能です:
<Android.support.design.widget.BottomNavigationView
app:labelVisibilityMode="labeled" />
またはプログラム的に設定 することもできます 。
注:古いバージョンのサポートライブラリからアップグレードする場合は、コンパイルSDKのバージョンを上げることを忘れないでください。サポートライブラリのバージョンをここで確認してください。 サポートライブラリのバージョン
ただし、アプリケーションが以前のバージョンのデザインサポートライブラリに依存している場合は、コンパイル時にlabelVisibilityModeが見つかりませんというメッセージが表示されることがあります。その場合は、少なくとも設計サポートライブラリのバージョン28.0.0-alpha1に依存する、指定された依存関係のバージョンにアップグレードしてみてください。それが不可能な場合は、依存関係を明示的に定義してください。
Gradleを使うなら
あなたのbuild.gradleで明示的に設計サポートの依存関係を追加するには:
実装 'com.Android.support:design:28.0.0'
デフォルトを使用して回答を更新しました。最新のデザインライブラリに更新する
実装 "com.Android.support:design:28.0.0"
そしてあなたのBottomNavigationView xml属性に置く
app:itemHorizontalTranslationEnabled="false"
プログラム的にも置くことができます
bottomNavigationView.setItemHorizontalTranslationEnabled(false);
あなたはここでソースを見つけることができます BottomNavigationView
これがお役に立てば幸いです。
更新
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());
}
}
}
あなたの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>
これは次のようになります
私はBottomNavigationViewでいくつかの奇妙な振る舞いをしました。その中の任意のアイテム/フラグメントを選択していたときに、フラグメントはBottomNavigationViewを少し下にプッシュします。そのため、BottomNavigationViewのテキストは画面の下に表示されます。
あなたがその奇妙なふるまいに直面しているなら、それからこれが解決策です。削除するだけ
Android:fitsSystemWindows="true"
フラグメントのルートレイアウトに。これを外してブームしてください。 BottomNavigationViewは問題なく動作しますが、テキストとアイコンで表示できるようになりました。私はこれをフラグメントのルートCoordinatorLayoutに持っていました。
また追加することを忘れないでください
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
あなたの活動の中でシフトモードを無効にする。それは尋ねられた質問と正確には関連していませんが、それでも私はこれが役に立ちます。
これは私が使っているサードパーティのライブラリで、シフトモードを無効にしたり、アイコンだけを表示したり、アイコンのサイズを設定したりなど、カスタマイズオプションがたくさんあります。 BottomNavigationViewEx
あなたもその迷惑な小さな上マージンアニメーションを取り除きたい場合は、より多くの反射コードが必要です。アニメーションを削除する完全な解決策は次のとおりです。
@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;
}
サポートライブラリを28.0.0に更新します。
bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
あなたがサポートを使用しているならば:デザイン:28.0.0あなたのBottomNavigationViewにこの行アプリを追加します:labelVisibilityMode = "unlabeled"
とても簡単です。BottomNaviationViewにプロパティを追加するだけです
app:labelVisibilityMode="unlabeled"
このメソッドに上記のdisableShiftModeコードを追加してください。 @SuppressLint( "RestrictedApi")