web-dev-qa-db-ja.com

BottomNavigationView-すべてのMenuItemsをオフにして、タイトルを表示したままにする方法

BottomNavigationViewのデザインが気に入ったので、単純なボタンを使用するのではなく、アプリに新しいメニューを実装することにしました。

ガイドラインとして this の投稿を採用しました。

BottomNavigationViewの-​​ documentation によると、その目的は

アプリのトップレベルビュー間をすばやく移動できます。それは主にモバイルで使用するために設計されています。

私の場合、各MenuItemにアクティビティを起動させたいだけですが、デフォルトでは常に1つのMenuItemが選択されています。

enter image description here

私は色を白に設定しようとしました:

app:itemIconTint="@color/white"
app:itemTextColor="@color/white"

それでも、目に見えるように選択されたMenuItemは他のものとは異なり(タイトルサイズが大きく)、それでも私は悩まされています。

enter image description here

非表示のMenuItemを配置して次のように選択するというアイデアが思い付きました。

<item
Android:id="@+id/uncheckedItem"
Android:title="" />

そしてそのビューをGONEにします:

 bottomNavigationView.getMenu().findItem(R.id.uncheckedItem).setChecked(true);
 bottomNavigationView.findViewById(R.id.uncheckedItem).setVisibility(View.GONE);

これにより、すべてのMenuItemsがオフになりますが、4番目のBottomNavigationViewMenuItemに落ち着いても、表示するMenuItemsが3つ以上あるため、デフォルトでGONEはTitlesを非表示にします。

enter image description here

だから私の質問は残っています、すべてのMenuItemの選択を解除してそのタイトルを表示したままにするための離れた場所/ハックはありますか?

16

this 投稿と私の進行状況をマージする自分のソリューションを見つけました。

手順:

  1. Proguard-rules.proを更新してビルドを同期
  2. ヘルパーを作成してBottomNavigationViewシフトモードを無効にする
  3. Menu.xmlで非表示にするアイテムを作成します
  4. BottomNavigationViewを膨らませる
  5. 非表示にするアイテムをチェック済みとして設定します
  6. ヘルパーを使用してシフトモードを無効にする

出力:

enter image description here

作業コード:

proguard-rules.pro:

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

BottomNavigationShiftHelper.Java:

public class BottomNavigationShiftHelper {

    private final static String TAG = "DEBUG_BOTTOM_NAV_UTIL";

    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);
                // set once again checked value, so view will be updated
                item.setChecked(item.getItemData().isChecked());
            }
        } catch (NoSuchFieldException e) {
            Log.d(TAG, "Unable to get shift mode field");
        } catch (IllegalAccessException e) {
            Log.d(TAG, "Unable to change value of shift mode");
        }
    }
}

Activity Sample.Java:

 private void loadNavigationBar() {
        BottomNavigationView bottomNavigationView = (BottomNavigationView)
                findViewById(R.id.navigation_bar);

        bottomNavigationView.getMenu().findItem(R.id.uncheckedItem).setChecked(true);
        bottomNavigationView.findViewById(R.id.uncheckedItem).setVisibility(View.GONE);

        BottomNavigationViewUtils.disableShiftMode(bottomNavigationView);

        bottomNavigationView.setOnNavigationItemSelectedListener(
                new BottomNavigationView.OnNavigationItemSelectedListener() {
                    @Override
                    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                        switch (item.getItemId()) {
                            case R.id.newList:
                                //Do The Math
                                break;
                            case R.id.loadList:
                                //Do The Math
                                break;
                            case R.id.settings:
                                //Do The Math
                                break;
                        }
                        return false;
                    }
                });
    }

BottomNavigationMenu.xml:

<?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/newList"
        Android:enabled="true"
        Android:icon="@drawable/new_list"
        Android:title="@string/common.button.list.new"
        app:showAsAction="withText" />
    <item
        Android:id="@+id/loadList"
        Android:enabled="true"
        Android:icon="@drawable/load"
        Android:title="@string/common.button.list.load"
        app:showAsAction="withText" />
    <item
        Android:id="@+id/settings"
        Android:enabled="true"
        Android:icon="@drawable/settings"
        Android:title="@string/common.label.settings"
        app:showAsAction="withText" />
    <item
        Android:id="@+id/uncheckedItem"
        Android:title="" />
</menu>

BottomNavigationComponent(Activity.xml内):

<Android.support.design.widget.BottomNavigationView
    Android:id="@+id/navigation_bar"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    app:itemIconTint="@color/white"
    app:itemTextColor="@color/white"
    Android:background="@drawable/BottomNavigationMenu.xml"
    app:menu="@menu/supercart_bottom_navigation" />
3
mNavigationBottom.getMenu().setGroupCheckable(0, false, true);
18
Rony Tesler

すべてのアイテムの選択を解除するには、この拡張機能を作成します。

fun BottomNavigationView.uncheckAllItems() {
    menu.setGroupCheckable(0, true, false)
    for (i in 0 until menu.size()) {
        menu.getItem(i).isChecked = false
    }
    menu.setGroupCheckable(0, true, true)
}

menu.setGroupCheckable(0、true、false)はそれを可能にします。 3番目のパラメーターはメニューを排他的ではなく、ループ内でチェック済みステータスを変更します。終了するには、メニューを再度排他に設定してください。

ここにドキュメント

9
user2003047

あなたのアイデアをありがとう。私は自分のlibにそれを実装しました。私はそれを反映することによってそれを行うより良い方法を持っています。したがって、スペースは表示されません。

興味があれば。ここをクリック: https://github.com/ittianyu/BottomNavigationViewEx

private void initBottomViewAndLoadFragments(final BottomNavigationViewEx bnve) {
    bnve.enableAnimation(false);
    bnve.enableShiftingMode(false);
    bnve.enableItemShiftingMode(false);

    // use the unchecked color for first item
    bnve.setIconTintList(0, getResources().getColorStateList(R.color.bnv_unchecked_black));
    bnve.setTextTintList(0, getResources().getColorStateList(R.color.bnv_unchecked_black));

    bnve.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {

        private boolean firstClick = true;
        private int lastItemId = -1;

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            // restore the color when click
            if (firstClick) {
                firstClick = false;
                bnve.setIconTintList(0, getResources().getColorStateList(R.color.selector_bnv));
                bnve.setTextTintList(0, getResources().getColorStateList(R.color.selector_bnv));
            }

            if (firstClick || lastItemId == -1 || lastItemId != item.getItemId()) {
                lastItemId = item.getItemId();
            } else {
                return false;
            }

            // do stuff
            return fillContent(item.getItemId());
        }
    });
}

-res/color/selector_bnv.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:color="@color/bnv_checked_white" Android:state_checked="true" />
    <item Android:color="@color/bnv_unchecked_black" />
</selector>

-res/values/colors.xml

<color name="bnv_checked_white">@Android:color/white</color>
<color name="bnv_unchecked_black">@Android:color/black</color>
5
ittianyu

あなたの解決策はアイテム間のスペースを変えるようです

私の解決策があります:

「クリックされた色をクリックされていない色と同じに設定するだけです。」

例えば:

private void changeMenuItemCheckedStateColor(BottomNavigationView bottomNavigationView, String checkedColorHex, String uncheckedColorHex) {
    int checkedColor = Color.parseColor(checkedColorHex);
    int uncheckedColor = Color.parseColor(uncheckedColorHex);

    int[][] states = new int[][] {
            new int[] {-Android.R.attr.state_checked}, // unchecked
            new int[] {Android.R.attr.state_checked}, // checked

    };

    int[] colors = new int[] {
            uncheckedColor,
            checkedColor
    };

    ColorStateList colorStateList = new ColorStateList(states, colors);

    bottomNavigationView.setItemTextColor(colorStateList);
    bottomNavigationView.setItemIconTintList(colorStateList);

}

すべてのアイテムのチェックを外したい場合は、

changeMenuItemCheckedStateColor(mBottomNavigationView, "#999999", "#999999");

色設定を復元したい場合は、

changeMenuItemCheckedStateColor(mBottomNavigationView, "FF743A", "999999");
2
楊舜淼

これは、以下のマークが付いた2行のコードを変更したことを除いて、受け入れられた回答と同じです。 BottomNavigationItemViewsをループするとき、checkedを常にfalseに設定し、checkableもfalseに設定しました。これにより、メニュー項目のサイズが変更されなくなります。あなたはまだこのプロガードルールが必要です:

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

更新されたコード:

    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);
                item.setShiftingMode(false);
                item.setChecked(false); // <--- This line changed
                item.setCheckable(false);  // <-- This line was added
            }
        }
        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");
        }

   }
0
tim.paetz

これを試してください、それは私のために働きました

 <item
    Android:id="@+id/uncheckedItem"
    Android:visible="false"
    Android:title="" />

そして設定

bottomNavigationView.getMenu().findItem(R.id.uncheckedItem).setChecked(true);

enter image description here

すべてのメニュー項目ビューが選択されていない状態で表示されます。選択はuncheckedItemに与えられているため、非表示です

お役に立てば幸いです。

0
Amrutha Saj

承認された回答には例外があり、そのコードを実装できない最大アイテムを設定しているため、承認されたコードよりもシンプルなコードを取得し、最大アイテムでも機能します。

私はここから参照しました BottomNavigationViewサポートAndroidのカスタムTextSize

Dimen.xmlには次のように配置できます。

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

これを行うと、BottomNavigationViewの内部クラスが使用するdimenのデフォルト値を上書きします。だから気をつけて。

下部のナビゲーションビューが初期化されたonCreateメソッドでこのコードを設定します

mNavigationBottom.getMenu().setGroupCheckable(0, false, true);

最後に、下のナビゲーションバーを次のように設定します。

 <com.google.Android.material.bottomnavigation.BottomNavigationView
    Android:id="@+id/nav_view"
    Android:layout_width="match_parent"
    Android:layout_height="?attr/actionBarSize"
    Android:layout_gravity="bottom"
    Android:background="?android:attr/windowBackground"
    Android:fitsSystemWindows="true"
    app:labelVisibilityMode="labeled"
    app:layout_anchorGravity="fill"
    app:menu="@menu/bottom_nav_menu" />

このセットでは、app:labelVisibilityModelabeledに設定します

最良の答えmNavigationBottom.getMenu().setGroupCheckable(0, false, true)はうまくいきませんでした。それでも、最初のアイテムが選択されていると表示されていました。

私にとってうまくいったのは、質問で行ったのとまったく同じように、非表示のアイテムを用意してそれを選択することです。

追加 app:labelVisibilityMode="labeled"BottomNavigationViewに追加すると、すべてのアイテムのタイトルが表示されたままになります。

0
Dan Bray