I have a bottom navigation view that has no icons, only text fields.
I want to center the text vertically & horizontally and added a highlight for the different states:
topnavigationview.setItemBackgroundResource(R.drawable.mainactivitybackgroundhighlight_top);
with the xml code:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/blau" android:state_pressed="true" />
<item android:drawable="@color/blau" android:state_checked="true" />
<item android:drawable="@color/dunkelgraublau" />
</selector>
The view is included like this:
<android.support.design.widget.BottomNavigationView
android:id="@+id/top_navigation_view"
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_below="@id/include4"
android:background="@color/dunkelgraublau"
app:itemTextColor="@color/weiß"
app:menu="@menu/top_navigation_menu" />
however, it now looks like this:
as you can see the highlight does not cover half of the menu, more like 40% of it; when selecting the right hand item its the same - despite the width being set to match_parent.
the text also is neither centered vertically nor horizontally;
1) how do i center the menu text vertically within the layout?
2) how do i make it so both menu items take up 50% of the navigation view? this would center the text horizontally and make the highlight take up 50% as intended.
The real answer is: don't do this. You're trying to use a support design library component that was created to look and feel a certain way, but you want to make it look and feel a different way. You should create your own view to behave the way you want.
But...
1) how do i center the menu text vertically within the layout?
Digging into the implementation for BottomNavigationView
, we eventually find that the menu items are represented by BottomNavigationItemView
objects (derived from FrameLayout
), which use this layout: https://github.com/dandar3/android-support-design/blob/master/res/layout/design_bottom_navigation_item.xml
As such, we can create a method to adjust the gravity and padding on the label views' parent so that they appear centered:
private static void adjustGravity(View v) {
if (v.getId() == android.support.design.R.id.smallLabel) {
ViewGroup parent = (ViewGroup) v.getParent();
parent.setPadding(0, 0, 0, 0);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) parent.getLayoutParams();
params.gravity = Gravity.CENTER;
parent.setLayoutParams(params);
}
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
adjustGravity(vg.getChildAt(i));
}
}
}
2) how do i make it so both menu items take up 50% of the navigation view?
The width of each menu item is constrained by this code in the BottomNavigationMenuView
class:
mActiveItemMaxWidth = res.getDimensionPixelSize( R.dimen.design_bottom_navigation_active_item_max_width);
There's no good way to modify this value, but we can do so using reflection:
private static void adjustWidth(BottomNavigationView nav) {
try {
Field menuViewField = nav.getClass().getDeclaredField("mMenuView");
menuViewField.setAccessible(true);
Object menuView = menuViewField.get(nav);
Field itemWidth = menuView.getClass().getDeclaredField("mActiveItemMaxWidth");
itemWidth.setAccessible(true);
itemWidth.setInt(menuView, Integer.MAX_VALUE);
}
catch (NoSuchFieldException e) {
// TODO
}
catch (IllegalAccessException e) {
// TODO
}
}
Once you have these methods in your activity, you can just write this:
BottomNavigationView nav = findViewById(R.id.top_navigation_view);
adjustGravity(nav);
adjustWidth(nav);
Note that, because each of these methods relies on internal implementation details of BottomNavigationView
, they are always subject to breakage when you update the support/design libraries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With