How to increase width of BottomNavigationView to fill the screen

后端 未结 3 1569
时光取名叫无心
时光取名叫无心 2021-01-07 15:01

How to increase width of BottomNavigationView menu. Below is the current scenario. I am not able to increase the width to complete screen.

Menu.xml

相关标签:
3条回答
  • 2021-01-07 15:34

    That is doable (Even without reflection). But it will againts default design specs, and I wil suggest you to go with default design specs.


    Now coming to my solution...

    Define below dimensions into dimens.xml. These dimensions should be in values, values-large, values-large-land and 600dp can be increased to 1000dp or more in values-large, values-large-land, if in tablet you are not seeing this change.

    <resources xmlns:tools="http://schemas.android.com/tools">
        <dimen name="design_bottom_navigation_item_max_width" tools:override="true">600dp</dimen>
        <dimen name="design_bottom_navigation_active_item_max_width" tools:override="true">600dp</dimen>
    </resources>
    

    And thats it!!! Result will be like


    It's not a mazic.

    Why dimensions has been added with such name and value is 600dp

    Both dimensions is being used by BottomNavigationMenuView.java (which is the class being used to represent menu in BottomNavigationView). Below is code

    public BottomNavigationMenuView(Context context, AttributeSet attrs) {
        super(context, attrs);
        ...
        mInactiveItemMaxWidth = res.getDimensionPixelSize(
                R.dimen.design_bottom_navigation_item_max_width);
        ....
        mActiveItemMaxWidth = res.getDimensionPixelSize(
                R.dimen.design_bottom_navigation_active_item_max_width);
        .....
    }
    

    Now these values is being used to create view with fixed width, as below

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        ....
        if (mShiftingMode) {
            final int inactiveCount = count - 1;
            final int activeMaxAvailable = width - inactiveCount * mInactiveItemMinWidth;
            final int activeWidth = Math.min(activeMaxAvailable, mActiveItemMaxWidth);
            final int inactiveMaxAvailable = (width - activeWidth) / inactiveCount;
            final int inactiveWidth = Math.min(inactiveMaxAvailable, mInactiveItemMaxWidth);
            ...
        } else {
            final int maxAvailable = width / count;
            final int childWidth = Math.min(maxAvailable, mActiveItemMaxWidth);
            .....
        }
        ....
    }
    

    To use value of activeMaxAvailable always, I set a dummy value to mActiveItemMaxWidth (in dimens above). So activeWidth will have value of activeMaxAvailable. Same rule apply for inactiveWidth.

    So when you build project, design_bottom_navigation_item_max_width and design_bottom_navigation_active_item_max_width defined into design-support-lib, will be replaced by dimensions defined by us.

    Code verified on maximum supported options (5 max) also.

    0 讨论(0)
  • 2021-01-07 15:46

    According to the BottomNavigationView specs: https://material.io/guidelines/components/bottom-navigation.html#specs-figure-caption-17

    Your navigation is correctly, but if anyway you want to expand the padding between the elements I recommend that you create your own bottom navigation using something like FlexBoxLayout: https://github.com/google/flexbox-layout

    0 讨论(0)
  • 2021-01-07 15:50

    i dont remember where i found this solution exactly but you use this helper class to disable item shifting for BottomNavigation using Java Reflection :

    import android.content.Context;
    import android.graphics.Typeface;
    import android.support.design.internal.BottomNavigationItemView;
    import android.support.design.internal.BottomNavigationMenuView;
    import android.support.design.widget.BottomNavigationView;
    import android.util.Log;
    import android.widget.TextView;
    import java.lang.reflect.Field;
    
    public class BottomNavigationViewHelper {
        public static void disableShiftMode(Context context,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);
    
                    Field LargeText = item.getClass().getDeclaredField("mLargeLabel");
                    LargeText.setAccessible(true);
                    Field SmallText = item.getClass().getDeclaredField("mSmallLabel");
                    SmallText.setAccessible(true);
    
    //                 TextView SmallTextView =(TextView) SmallText.get(item);
    //                 TextView LargeTextView =(TextView) LargeText.get(item);
    
    //                 Typeface tf = TypefaceHelper.getTypeface(context);
    //                 SmallTextView.setTypeface(tf);
    //                 LargeTextView.setTypeface(tf);
    
                    //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);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题