BottomNavigationView - How to uncheck all MenuItems and keep Titles being displayed?

后端 未结 10 1240
面向向阳花
面向向阳花 2020-12-18 19:33

As I liked the design from BottomNavigationView I decided to implement a new Menu for my App with it, instead of just using simple buttons.

I took this

相关标签:
10条回答
  • 2020-12-18 20:09

    I found my own solution merging my progress with this post.

    Steps:

    1. Update proguard-rules.pro and sync build
    2. Create Helper to disable BottomNavigationView Shift Mode
    3. Create an Item to hide on Menu.xml
    4. Inflate BottomNavigationView
    5. Set Item to be hidden as Checked GONE
    6. Use Helper to disable Shifting Mode

    Output:

    Working code:

    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 (inside 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" />
    
    0 讨论(0)
  • 2020-12-18 20:10
    mNavigationBottom.getMenu().setGroupCheckable(0, false, true);
    
    0 讨论(0)
  • 2020-12-18 20:10

    There is an exception in accepted answer which we set maximum item we cant implement that code.So I got a code that is more simple than accepted code and it's also working with maximum item.

    I referred from here Custom TextSize of BottomNavigationView support android

    In your dimen.xml you can put:

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

    Doing this you are overriding the default value of dimen that the internal classes of BottomNavigationView use. So be carreful.

    Set this code in your onCreate method where the bottom navigation view initialized

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

    and Last set your bottom navigation bar like this :

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

    In this set your app:labelVisibilityMode to labeled

    0 讨论(0)
  • 2020-12-18 20:11

    Thanks for your idea. I have implement it in my lib. I have a better way do it by reflect. So it won't show space.

    If you have interest. Click here : 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>
    
    0 讨论(0)
提交回复
热议问题