Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set default menuItem for BottomNavigationView

How can i set the default MenuItem for the official BottomNavigationView (com.android.support:design:25.0.1)?

If I call programmatically menuItem.setCheckable(true).setChecked(true) the zoom effect is not performed and the BottomNavigationView shows like this:

BottomNavigationView

like image 253
Bronx Avatar asked Nov 25 '16 09:11

Bronx


3 Answers

There is more simpler way to do this since Android Support Library 25.3.0 :

bottomNavigationView.setSelectedItemId(R.id.id_of_item_you_want_to_select_as_default);
like image 194
Fadwa_lmh Avatar answered Nov 18 '22 11:11

Fadwa_lmh


I achieved this in a much simpler way:

    //R.id.bottom_bar_icon is the icon you would like clicked by default
    bottomNavigationView.getMenu().performIdentifierAction(R.id.bottom_bar_icon, 0);

    //set the corresponding menu item to checked = true
    //and the other items to checked = false
    bottomNavigationView.getMenu().getItem(0).setChecked(false);
    bottomNavigationView.getMenu().getItem(1).setChecked(true);
    bottomNavigationView.getMenu().getItem(2).setChecked(false);
like image 25
Avery Pelle Avatar answered Nov 18 '22 09:11

Avery Pelle


In the end I was able to achieve this issue extending the BottomNavigationView like this:

public class RichBottomNavigationView  extends BottomNavigationView {
private ViewGroup mBottomItemsHolder;
private int mLastSelection = INVALID_POSITION;
private Drawable mShadowDrawable;
private boolean mShadowVisible = true;
private int mWidth;
private int mHeight;
private int mShadowElevation = 2;

public RichBottomNavigationView(Context context) {
    super(context);
    init();
}

public RichBottomNavigationView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public RichBottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
    ;
}


private void init() {
    mShadowDrawable = ContextCompat.getDrawable(getContext(), R.drawable.shadow);
    if (mShadowDrawable != null) {
        mShadowDrawable.setCallback(this);
    }
    setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
    setShadowVisible(true);
    setWillNotDraw(false);

}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h + mShadowElevation, oldw, oldh);
    mWidth = w;
    mHeight = h;
    updateShadowBounds();
}


private void updateShadowBounds() {
    if (mShadowDrawable != null && mBottomItemsHolder != null) {
        mShadowDrawable.setBounds(0, 0, mWidth, mShadowElevation);
    }
    ViewCompat.postInvalidateOnAnimation(this);
}

@Override
public void draw(Canvas canvas) {
    super.draw(canvas);
    if (mShadowDrawable != null && mShadowVisible) {
        mShadowDrawable.draw(canvas);
    }
}

public void setShadowVisible(boolean shadowVisible) {
    setWillNotDraw(!mShadowVisible);
    updateShadowBounds();
}

public int getShadowElevation() {
    return mShadowVisible ? mShadowElevation : 0;
}

public int getSelectedItem() {
    return mLastSelection = findSelectedItem();
}

@CallSuper
public void setSelectedItem(int position) {
    if (position >= getMenu().size() || position < 0) return;

    View menuItemView = getMenuItemView(position);
    if (menuItemView == null) return;
    MenuItemImpl itemData = ((MenuView.ItemView) menuItemView).getItemData();


    itemData.setChecked(true);

    boolean previousHapticFeedbackEnabled = menuItemView.isHapticFeedbackEnabled();
    menuItemView.setSoundEffectsEnabled(false);
    menuItemView.setHapticFeedbackEnabled(false); //avoid hearing click sounds, disable haptic and restore settings later of that view
    menuItemView.performClick();
    menuItemView.setHapticFeedbackEnabled(previousHapticFeedbackEnabled);
    menuItemView.setSoundEffectsEnabled(true);


    mLastSelection = position;

}


@Override
protected Parcelable onSaveInstanceState() {
    Parcelable superState = super.onSaveInstanceState();
    BottomNavigationState state = new BottomNavigationState(superState);
    mLastSelection = getSelectedItem();
    state.lastSelection = mLastSelection;
    return state;
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
    if (!(state instanceof BottomNavigationState)) {
        super.onRestoreInstanceState(state);
        return;
    }
    BottomNavigationState bottomNavigationState = (BottomNavigationState) state;
    mLastSelection = bottomNavigationState.lastSelection;
    dispatchRestoredState();
    super.onRestoreInstanceState(bottomNavigationState.getSuperState());
}

private void dispatchRestoredState() {
    if (mLastSelection != 0) { //Since the first item is always selected by the default implementation, dont waste time
        setSelectedItem(mLastSelection);
    }
}

private View getMenuItemView(int position) {
    View bottomItem = mBottomItemsHolder.getChildAt(position);
    if (bottomItem instanceof MenuView.ItemView) {
        return bottomItem;
    }
    return null;
}

private int findSelectedItem() {
    int itemCount = getMenu().size();
    for (int i = 0; i < itemCount; i++) {
        View bottomItem = mBottomItemsHolder.getChildAt(i);
        if (bottomItem instanceof MenuView.ItemView) {
            MenuItemImpl itemData = ((MenuView.ItemView) bottomItem).getItemData();
            if (itemData.isChecked()) return i;
        }
    }
    return INVALID_POSITION;
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    mBottomItemsHolder = (ViewGroup) getChildAt(0);
    updateShadowBounds();
    //This sucks.
    MarginLayoutParams layoutParams = (MarginLayoutParams) mBottomItemsHolder.getLayoutParams();
    layoutParams.topMargin = (mShadowElevation + 2) / 2;
}

static class BottomNavigationState extends BaseSavedState {
    public int lastSelection;

    @RequiresApi(api = Build.VERSION_CODES.N)
    public BottomNavigationState(Parcel in, ClassLoader loader) {
        super(in, loader);
        lastSelection = in.readInt();
    }

    public BottomNavigationState(Parcelable superState) {
        super(superState);
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeInt(lastSelection);
    }

    public static final Parcelable.Creator<NavigationView.SavedState> CREATOR
            = ParcelableCompat.newCreator(new ParcelableCompatCreatorCallbacks<NavigationView.SavedState>() {
        @Override
        public NavigationView.SavedState createFromParcel(Parcel parcel, ClassLoader loader) {
            return new NavigationView.SavedState(parcel, loader);
        }

        @Override
        public NavigationView.SavedState[] newArray(int size) {
            return new NavigationView.SavedState[size];
        }
    });
}
}

and calling setSelectedItem(2)

like image 41
Bronx Avatar answered Nov 18 '22 10:11

Bronx