[android] 3 개 이상의 항목이있는 BottomNavigationView : 탭 제목이 숨겨져 있습니다.

Android Support Desing Library 25를 사용하여 BottomNavigationView를 사용하고 있습니다.하지만 탭을 전환하면 다른 탭의 제목이 숨겨집니다. 그러나 실제 하단 탐색 뷰에는 숨어있는 문제가 없습니다. 하지만 내 것은 숨어있다.

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>



답변

반사를 사용하는 솔루션은 mShiftingMode 필드가 제거 되었기 때문에 더 이상 작동하지 않습니다.

이제 쉽게 할 수있는 방법이 있습니다. 지원 라이브러리 28을 사용하고 XML 선언에 추가 app:labelVisibilityMode="labeled"하기 만하면 BottomNavigationView됩니다.

도움이되기를 바랍니다.


답변

최신 정보

지원 라이브러리 28.0.0-alpha1에서 이제 Labels를 추가 할 수 있으므로 removeShiftMode () 가 더 이상 필요하지 않습니다 .

XML에서 :

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

프로그래밍 방식으로 변경하는 경우 :

mBottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

이를 위해 : 설계 지원 라이브러리를 28.0.0-alpha1 로 업데이트하십시오.

다음은 좋은 읽기입니다.

이전 지원 라이브러리의 경우 :

당신의 bottom_bar_menu.xml.Change showAsAction속성

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

build.gradle에서 :

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

하단 탐색 3 개 이상의 항목보기 : 사용 removeShiftMode()방법

BottomNavigationViewHelper.java사용 :

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);
            }
        }
    }

다음을 사용하여 호출하십시오.

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

제목 텍스트의 이동 애니메이션을 비활성화하고 텍스트를 표시 할 수 있습니다.


답변

BottomNavigationView의 소스 코드를 스캔 한 후

mShiftingMode = mMenu.size() > 3;

BottomNavigationMenuView.java의 선 (265)는 메뉴의 크기보다 3 이상 동안 탭 타이틀 HID 수 wiil 의미한다. 따라서 탭 제목을 표시하려면 빌드에서 코드를 가져 와서 아래로 변경하면됩니다.

mShiftingMode = mMenu.size() > 5;

PS : BottonNavigationView 최대 탭 카운트해야 당신은에 코드를 얻을 수 3과 5 사이 BottomNavigationViewNew
여기에 이미지 설명 입력


답변

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);
        }
    }
}

요구

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


답변

Kotlin 확장 기능 :

@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")
    }
}


답변

나는 rafsanahmad007 답변을 거의 사용 했지만 Kotlin으로 번역합니다. 미래의 방랑자들을 위해 공유하겠습니다.

@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")
    }
}


답변

이것은 API 26에서 저에게 효과적입니다.

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


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

호출하려는 Activity 또는 Fragment에서이 메서드를 만듭니다.

 @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) {

    }
}