拥有3个以上项目的 BottomNavigationView: 标签标题被隐藏

我使用 BottomNavigationView 和 Android 支持设计库25。 但当我切换标签时,另一个标签的标题就隐藏起来了。但是实际的底部导航视图没有隐藏问题。但我的却藏起来了。

MyBottomNavigation

但我想让它看起来像那样,有什么办法吗? 我错过了什么?

ActualBottomNavigation

这是我的代码:

Activity _ main. xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.yunus.ototakip.MainActivity">


<FrameLayout
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom_navigation"
android:layout_alignParentTop="true">
</FrameLayout>


<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="@color/colorPrimary"
app:itemIconTint="@color/beyaz"
app:itemTextColor="@color/beyaz"
app:menu="@menu/bottombar_menu" />

Bottom _ bar _ menu. xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/bb_menu_arac"
android:enabled="true"
android:icon="@drawable/icon_car"
android:title="@string/araclarim"
app:showAsAction="ifRoom" />
<item
android:id="@+id/bb_menu_yakin"
android:enabled="true"
android:icon="@drawable/icon_yer"
android:title="@string/yakinimdakiler"
app:showAsAction="ifRoom" />
<item
android:id="@+id/bb_menu_yaklasan"
android:enabled="true"
android:icon="@drawable/icon_takvim"
android:title="@string/yaklasanlar"
app:showAsAction="ifRoom" />


<item
android:id="@+id/bb_menu_ipucu"
android:enabled="true"
android:icon="@drawable/icon_ipucu"
android:title="@string/ipuclari"
app:showAsAction="ifRoom" />
</menu>
64296 次浏览

UPDATE

removeShiftMode() is no longer needed, as in support library 28.0.0-alpha1 we can now add Labels.

In XML:

<android.support.design.widget.BottomNavigationView
app:labelVisibilityMode="labeled" />

For programmatically change:

mBottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

For this to work: update the design support library to 28.0.0-alpha1

Here is a Good read

FOR OLDER SUPPORT LIBRARY:

in your bottom_bar_menu.xml.Change the showAsAction attribute

<item android:id="@id/menu_item"
android:title="text"
android:icon="@drawable/drawable_resource_name"
android:showAsAction="always|withText" />

in build.gradle:

compile 'com.android.support:design:25.3.1'

BOTTOM NAVIGATIONVIEW MORE THAN 3 ITEMS: use removeShiftMode() method

in BottomNavigationViewHelper.java Use:

import android.annotation.SuppressLint;
import android.support.design.internal.BottomNavigationItemView;
import android.support.design.internal.BottomNavigationMenuView;
import android.support.design.widget.BottomNavigationView;
import java.lang.reflect.Field;


public class BottomNavigationViewHelper {
@SuppressLint("RestrictedApi")
public 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);
//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("BottomNav", "Unable to get shift mode field", e);
} catch (IllegalAccessException e) {
Log.e("BottomNav", "Unable to change value of shift mode", e);
}
}
}

Call it using:

BottomNavigationView bottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_navigation);
BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);

It will disable the shift animation of the title text and enable the text to be displayed.

After scan source code of BottomNavigationView I find

mShiftingMode = mMenu.size() > 3;

in BottomNavigationMenuView.java line 265, it means while menu size more than 3, tab title wiil be hid. So if you want to show tab title you just need to get code from build and change to below.

mShiftingMode = mMenu.size() > 5;

PS: BottonNavigationView max tab count must between 3 and 5. You can get code on BottomNavigationViewNew enter image description here

Create Class BottomNavigationViewHelper

import android.annotation.SuppressLint;
import android.support.design.internal.BottomNavigationItemView;
import android.support.design.internal.BottomNavigationMenuView;
import android.support.design.widget.BottomNavigationView;
import android.util.Log;
import java.lang.reflect.Field;
public class BottomNavigationViewHelper {
@SuppressLint("RestrictedApi")
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);
if(menuView.getChildCount()<6)
{
for (int i = 0; i < menuView.getChildCount(); i++) {
BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
//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);
}
}
}

Call

    BottomNavigationView bottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_navigation);
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

I pretty much used rafsanahmad007 answer but translate it to Kotlin. Let me share it for the future wanderers

@SuppressLint("RestrictedApi")
fun BottomNavigationView.disableShiftMode() {
val menuView = this.getChildAt(0) as BottomNavigationMenuView
try {
val shiftingMode = menuView::class.java.getDeclaredField("mShiftingMode")
shiftingMode.setAccessible(true)
shiftingMode.setBoolean(menuView, false)
shiftingMode.setAccessible(false)
for (i in 0..(menuView.childCount - 1)) {
val item = menuView.getChildAt(i) as BottomNavigationItemView
item.setShiftingMode(false)
// set once again checked value, so view will be updated
item.setChecked(item.getItemData().isChecked())
}
} catch (e: NoSuchFieldException) {
Timber.e("Unable to get shift mode field")
} catch (e: IllegalAccessException) {
Timber.e("Unable to change value of shift mode")
}
}

The solution using reflection doesn't work anymore because the field mShiftingMode was removed.

There's an easy way to do it now: Use Support Library 28 or higher and just add app:labelVisibilityMode="labeled" to your BottomNavigationView XML declaration.

Hope it helps.

Kotlin extension function:

@SuppressLint("RestrictedApi")
fun BottomNavigationView.removeShiftMode(){
val menuView = this.getChildAt(0) as BottomNavigationMenuView
try {
val shiftingMode = menuView.javaClass.getDeclaredField("mShiftingMode")
shiftingMode.isAccessible = true
shiftingMode.setBoolean(menuView, false)
shiftingMode.isAccessible = false
for (i in 0 until menuView.childCount) {
val item = menuView.getChildAt(i) as BottomNavigationItemView
item.setShiftingMode(false)
// set once again checked value, so view will be updated
item.setChecked(item.itemData.isChecked)
}
} catch (e: NoSuchFieldException) {
e.printStackTrace()
Timber.tag("BottomNav").e( e, "Unable to get shift mode field")
} catch (e: IllegalAccessException) {
Timber.tag("BottomNav").e( e, "Unable to change value of shift mode")
}
}

This works for me in API 26 :

 navigation = (BottomNavigationView) view.findViewById(R.id.bottom_navigation);




try{disableShiftMode(navigation);}catch(Exception ew){}

Make this method in your Activity or Fragment where you want to call:

 @SuppressLint("RestrictedApi")
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);


item.setChecked(item.getItemData().isChecked());
}
} catch (NoSuchFieldException e) {


} catch (IllegalAccessException e) {


}
}

You can use this for showing both text and icons on BottomNevigationView for 3 to 5 items and stop shifting.

 app:labelVisibilityMode="labeled"

But you will will face a problem of long text cutting on BottmNevigationView for 5 items. for that ,I found a good solutions for stop shifting of text as well as icons of BottomNevigationView. You can also stop shifting of text as well as Icons on BottomNevigationView also. Snipshots of code is given here.

1. Add this some line of code in BottomNevigationView as shown

<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="@dimen/seventy_dp"
android:layout_semitransparent="true"
android:background="@color/colorBottomNev"
android:showAsAction="always|withText"
app:itemIconTint="@drawable/bottom_navigation_colors"
app:itemTextColor="@drawable/bottom_navigation_colors"
app:itemTextAppearanceActive="@style/BottomNavigationViewTextStyle"
app:itemTextAppearanceInactive="@style/BottomNavigationViewTextStyle"
app:menu="@menu/bottom_navigation_menu"
app:labelVisibilityMode="labeled"/>

2. Add Menu Items like as follows:-

 <?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/action_catalogue"
android:icon="@drawable/catalogue"
android:title="@string/catalogue"
android:enabled="true"
app:showAsAction="ifRoom" />


<item
android:id="@+id/action_contracts"
android:icon="@drawable/contract"
android:title="@string/contracts"
android:enabled="true"
app:showAsAction="ifRoom" />


<item
android:id="@+id/action_prospects"
android:icon="@drawable/prospect"
android:title="@string/prospects"
android:enabled="true"
app:showAsAction="ifRoom" />


<item
android:id="@+id/action_performance"
android:icon="@drawable/performance"
android:title="@string/performance"
android:enabled="true"
app:showAsAction="ifRoom" />


<item
android:id="@+id/action_advance"
android:icon="@drawable/advance"
android:title="@string/advance"
android:enabled="true"
app:showAsAction="ifRoom" />


</menu>

3.Add this style in style.xml file:

 <style name="BottomNavigationViewTextStyle">
<item name="android:fontFamily">@font/montmedium</item>
<item name="android:textSize">10sp</item>
<item name="android:duplicateParentState">true</item>
<item name="android:ellipsize">end</item>
<item name="android:maxLines">1</item>
</style>

4)Add these in Dimen folder

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<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>
</resources>

I got help from these link and link .You can also get get help by studying these links.This helps me a lot.Hope this also help you. Thanks....

quick fixed just add app:labelVisibilityMode="labeled" in xml

<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="@color/colorPrimary"
app:itemIconTint="@drawable/bottom_navigation_color_selector"
app:itemTextColor="@drawable/bottom_navigation_color_selector"
app:labelVisibilityMode="labeled"
app:menu="@menu/menu_bottom_navigation" />

Note

  implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'

One thing to note even though it does not apply in this case.

This pattern can be used when you have between 3 and 5 top-level destinations to navigate to.

To enable the icon title to display do the following:

  1. Make sure your menu (bottom_navigation_menu) item XML is structured as follows:-

    <item
    android:id="@+id/action_home"
    android:enabled="true"
    android:icon="@drawable/ic_action_home"
    android:title="HOME"
    app:showAsAction="ifRoom"/>
    
    
    <item
    android:id="@+id/action_favourites"
    android:enabled="true"
    android:icon="@drawable/ic_action_favourite"
    android:title="FAVOURITES"
    app:showAsAction="ifRoom"/>
    
    
    <item
    android:id="@+id/action_basket"
    android:enabled="true"
    android:icon="@drawable/ic_action_basket"
    android:title="BASKET"
    app:showAsAction="ifRoom"/>
    

  2. Add the following to the BottomNavigationView code app:labelVisibilityMode="labeled"

<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@android:color/white"
app:itemIconTint="@android:color/black"
app:itemTextColor="@android:color/black"
app:menu="@menu/bottom_navigation_menu"
app:labelVisibilityMode="labeled"/>

app:labelVisibilityMode="labeled"

Add above code under your XML file.

Example:

xmlns:app="http://schemas.android.com/apk/res-auto"




<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav_view"
....
....
app:labelVisibilityMode="labeled"/>