BottomNavigationView 시프트 모드를 비활성화하는 방법은 무엇입니까?


146

BottomNavigationView에는 비활성화 된 메뉴 제목이 표시되지 않습니다.

bottomNavigationBar에서 모든 메뉴 요소의 제목을 표시하는 방법은 무엇입니까? 문제는 필자의 경우 클릭 한 요소의 제목 만 표시한다는 것입니다.

여기에 이미지 설명을 입력하십시오



다음은 애니메이션 을 완전히 제거 하려는 경우 유용한 답변입니다 . stackoverflow.com/a/51052247/2352699
Fred Porciúncula 2018 년

답변:


330

구현 BottomNavigationView에는 조건이 있습니다. 3 개 이상의 항목이있는 경우 시프트 모드를 사용하십시오.

현재로서는 기존 API를 통해이를 변경할 수 없으며 시프트 모드를 비활성화하는 유일한 방법은 리플렉션을 사용하는 것입니다.

도우미 수업이 필요합니다.

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

그런 다음에 disableShiftMode메소드 를 적용 BottomNavigationView하지만 코드에서 메뉴보기를 부 풀리면 부풀린 후에 실행해야합니다.

사용법 예 :

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

추신.

의 메뉴 항목을 변경할 때마다이 방법을 실행해야합니다 BottomNavigationView.

최신 정보

또한 proguard 구성 파일 (예 : proguard-rules.pro)을 업데이트해야합니다. 위의 코드는 리플렉션을 사용하며 proguard가 mShiftingMode필드를 난독 화하면 작동하지 않습니다 .

-keepclassmembers class android.support.design.internal.BottomNavigationMenuView { 
    boolean mShiftingMode; 
}

가리키는 주셔서 감사합니다 무하마드 Alfaifi 이 문제를미리보기를 제공합니다 .

업데이트 2

Jolanda Verhoef가 지적한대로 새로운 지원 라이브러리 ( 28.0.0-alpha1)와 새로운 재료 구성 요소 라이브러리 ( 1.0.0-beta01)는 3 개의 메뉴 항목에서 이동 모드를 조작하는 데 사용할 수있는 공용 속성을 제공합니다.

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

재료 구성 요소 라이브러리에는 5 개의 메뉴 항목이있는 경우에도 적용됩니다.

업데이트 3

@ThomasSunderland도 지적했듯이 애니메이션 후행 을 비활성화하기 위해 접미사 app:itemHorizontalTranslation="false"없이이 속성을 false로 설정할 수 있습니다 Enabled.

여기서 BottomNavigation 스타일링에 대한 전체 가이드를 확인할 수 있습니다.


10
**** Proguard :(
Muhammad Alfaifi

17
proguard-rules 파일에서 필드를 제외하지 않으면 필드가 난독 처리되므로 값을 변경할 수 없습니다.
Muhammad Alfaifi

8
-keepclassmembers class android.support.design.internal.BottomNavigationMenuView {부울 mShiftingMode; }
Muhammad Alfaifi

8
때로는 Google이 개발자에게보기 구현을 강요하는 이유가 궁금합니다. Google+ 앱 자체에는 4 가지 옵션이 있지만이 간단한 기능은 간단한 기능을 통해 액세스 할 수 있어야합니다. 지원 라이브러리에서 나중에 많이 수정 된 TabLayout과 비슷한 문제가있었습니다. 개선을위한 Original Replier 및 @MuhammadAlfaifi의 해결 방법에 감사드립니다.
sud007

19
labelVisibilityMode을 = "표시": 새로운 지원 라이브러리 (28.0.0 - 알파 1) 지원은 응용 프로그램을 통해이 동작을 변경
란다 Verhoef

50

지원 라이브러리 28.0.0-alpha1 이후 :

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

1
이 지원 라이브러리 버전을 사용하고 있는데 "labelVisibilityMode"에 오류가 계속 발생합니다.
Sagar Maiyad

1
제대로 작동합니다. 반성을 위해 갈 필요가 없습니다. 고마워 톤
Bhupesh

1
@Riser 사용 app:하지 않는지 확인하십시오android:
Carson Holzheimer

28

텍스트 애니메이션을 비활성화하려면 dimens.xml 파일에서이를 사용할 수도 있습니다.

<dimen name="design_bottom_navigation_active_text_size">12sp</dimen>

매니페스트에 이것을 추가해야 할 수도 있습니다.

tools:override="true"

작동하지 않는. /values/dimens.xml에 이것을 추가해야한다고 생각합니까?
Rohan Kandwal

10
@RohanKandwal 추가해야tools:override="true"
Boy

@Boy 감사합니다, 시도합니다.
Rohan Kandwal

텍스트 크기 만 변경하십시오.
친구

난 그냥 내 dimens.xml 파일에 다음과 같이 넣어해야합니다<dimen name="design_bottom_navigation_active_text_size" tools:ignore="PrivateResource">12sp</dimen>
페르난도 바르보사를

22

이제 사용할 수 app:labelVisibilityMode="[labeled, unlabeled, selected, auto]"있는28-alpha

  • labeled 모든 라벨을 볼 수 있습니다.
  • unlabeled 아이콘 만 표시됩니다.
  • selected 선택한 항목 및 이동 항목의 레이블 만 표시합니다.
  • auto가지고있는 항목 수에 따라 레이블이 있거나 선택됩니다. 1-3 개 항목에 레이블이 지정되고 3 개 이상의 항목에 선택됩니다.

1
고마워 Lunkie! 이것은 저에게 가장 쉽고 쉬운 솔루션입니다
Gregriggins36

이 코드 줄을 추가 할 위치 추가하려고했지만 오류를 찾을 수 없습니다.
Abdulwahid

@Abdulwahid 라이브러리 28 이상을 지원하면 하단 네비게이션 바의 xml에 이것을 추가 할 수 있습니다
Aidan Laing

@Lunkie 덕분에 이제 한 번 지원 라이브러리 28
Abdulwahid

17

확장 기능으로 Kotlin에서 Przemysław의 답변

@SuppressLint("RestrictedApi")
fun BottomNavigationView.disableShiftMode() {
    val menuView = getChildAt(0) as BottomNavigationMenuView
    try {
        val shiftingMode = menuView::class.java.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) {
        Log.e(TAG, "Unable to get shift mode field", e)
    } catch (e: IllegalStateException) {
        Log.e(TAG, "Unable to change value of shift mode", e)
    }
}

사용법 (Kotlin Android Extensions 사용) :

bottom_navigation_view.disableShiftMode()

kotlin에서 일하고 있습니다. 왜 우리가이 주석을 사용해야 하는가 @SuppressLint ( "RestrictedApi") pls를 설명 할 수 있습니까?
Ranjith Kumar

11

나를 위해 작동

bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

또는

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

내 목표는 27까지 잘 작동했지만 target = 28에서는 텍스트가 더 이상 표시되지 않습니다. 그러나 setLabelVisibilityMode 지금, 나를 위해 트릭을 수행하는 매력처럼 작동
joke4me

10

텍스트 애니메이션을 비활성화하고 글꼴 크기를 줄이려면 dimens.xml 파일에서 다음을 사용하십시오.

<dimen name="design_bottom_navigation_text_size">10sp</dimen> 
<dimen name="design_bottom_navigation_active_text_size">10sp</dimen>

하나는 수 Navigate-> File...> design_bottom_navigation_item.xml다른 방법이 없다는 것을 확인합니다.
arekolek

6

최신 정보

Android SDK 버전 28 이상에서는 다음으로 변경 item.setShiftingMode(false)되었습니다.item.setShifting(false)

또한 그들은 필드를 제거 mShiftingMode

그래서 사용법은

 BottomNavigationHelper.removeShiftMode(bottomNav);
 bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);


 private static final class BottomNavigationHelper {
    @SuppressLint("RestrictedApi")
    static void removeShiftMode(BottomNavigationView view) {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        for (int i = 0; i < menuView.getChildCount(); i++) {
            BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
            //noinspection RestrictedApi
            item.setShifting(false);
            item.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

            // set once again checked value, so view will be updated
            //noinspection RestrictedApi
            item.setChecked(item.getItemData().isChecked());
        }
    }
}

아래 코드를 사용할 수 있습니다. @SuppressLint ( "RestrictedApi") fun removeShiftMode (view : BottomNavigationView) {val menuView = view.getChildAt (0) as BottomNavigationMenuView menuView.labelVisibilityMode = LabelVisibilityMode.LABEL_VISIBILITY_LABELED menuView.buildMenuView ()}
Deep P

5

다른 사람들이 지적했듯이 지원 라이브러리 28.0.0-alpha1 부터 가능합니다.

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

또는 프로그래밍 방식으로 설정할 수 있습니다 .

참고 : 이전 버전의 지원 라이브러리에서 업그레이드하는 경우 컴파일 SDK 버전을 올리는 것을 잊지 마십시오. 지원 라이브러리 버전 확인 : 지원 라이브러리 버전

그러나 앱이 이전 버전의 디자인 지원 라이브러리에 의존하는 경우 컴파일 할 때 labelVisibilityMode not found 메시지 가 계속 표시 될 수 있습니다. 이 경우, 최소한 28.0.0-alpha1의 디자인 지원 라이브러리 버전에 따라 지정된 종속성 버전으로 업그레이드하십시오. 이것이 가능하지 않으면 종속성을 명시 적으로 정의하십시오.

Gradle을 사용하는 경우

  1. 의존성 작업 을 실행하여 depdendecies를 확인 하고 com.android.support:design 의 버전 번호를 검색 할 수 있습니다 .
  2. build.gradle에 명시 적으로 디자인 지원 종속성을 추가하려면 다음을 수행하십시오 .

    구현 'com.android.support:design:28.0.0'


4

기본값을 사용하여 업데이트 된 답변. 최신 디자인 라이브러리로 업데이트

구현 "com.android.support:design:28.0.0"

BottomNavigationView xml 속성에 넣습니다.

app:itemHorizontalTranslationEnabled="false"

프로그래밍 방식으로 넣을 수도 있습니다

bottomNavigationView.setItemHorizontalTranslationEnabled(false);

여기서 소스를 찾을 수 있습니다. BottomNavigationView

이것이 도움이되기를 바랍니다.


이것은 무엇과 다른가 app:labelVisibilityMode?
wonsuc

@wonsuc 이것은 선택된 항목이 애니메이션을 적용하는 아이콘과 텍스트의 애니메이션에 관한 것입니다. labelVisibilityMode는 텍스트와 함께 아이콘을 표시 할 것인지 또는 선택시 표시 될 아이콘 만 표시 할 것인지를 표시합니다.
Lester L.

3

당신의 BottomNavigationView추가app:labelVisibilityMode="unlabeled"

<android.support.design.widget.BottomNavigationView
        app:menu="@menu/bn_menu"
        android:layout_height="56dp"
        android:layout_width="match_parent"
        app:labelVisibilityMode="unlabeled">

</android.support.design.widget.BottomNavigationView>

결과는 다음과 같습니다.

Android 하단 탐색보기 텍스트 및 이동 비활성화


3

매우 간단합니다. BottomNaviationView에 속성을 추가하십시오.

app:labelVisibilityMode="unlabeled"

2

BottomNavigationView에 이상한 동작이있었습니다. 항목 / 조각을 선택할 때 프래그먼트가 BottomNavigationView를 약간 아래로 밀기 때문에 BottomNavigationView의 텍스트가 화면 아래로 이동하므로 아이콘 만 표시되고 항목을 클릭하면 텍스트 만 숨겨집니다.

그 이상한 행동에 직면하고 있다면 여기에 해결책이 있습니다. 그냥 제거

android:fitsSystemWindows="true"

조각의 루트 레이아웃에서. 이것을 제거하고 붐! BottomNavigationView가 정상적으로 작동하므로 이제 텍스트와 아이콘으로 표시 할 수 있습니다. 나는 이것을 루트 코디네이터 레이아웃의 조각에 가지고있었습니다.

또한 추가하는 것을 잊지 마십시오

BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

활동에서 변속 모드를 비활성화하십시오. 그것은 묻는 질문과 정확히 관련이 없지만 여전히 도움이됩니다.


1
@ abbath0767이 링크를 보셨습니까 ? 도움이 될 수 있습니다.
Kishan Solanki

나는 이미 모든 것을 시험해 보았고 매우 감사하며 내가 찾고있는 답을 직접 찾지 않을 것이라고 생각했습니다.
BekaBot

1
즐거움 @BekaBot
Kishan Solanki

2

이것은 내가 사용하는 타사 라이브러리이며 시프트 모드 비활성화, 아이콘 만 표시, 아이콘 크기 설정 등과 같은 많은 사용자 정의 옵션이 있습니다. BottomNavigationViewEx


2

애니메이션을 완전히 제거하려면

성가신 작은 상단 여백 애니메이션을 제거하려면 더 많은 리플렉션 코드가 필요합니다. 모든 애니메이션을 제거하는 완벽한 솔루션은 다음과 같습니다.

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

            Field shiftAmount = item.getClass().getDeclaredField("mShiftAmount");
            shiftAmount.setAccessible(true);
            shiftAmount.setInt(item, 0);
            shiftAmount.setAccessible(false);

            item.setChecked(item.getItemData().isChecked());
        }
    } catch (NoSuchFieldException e) {
        Timber.e(e, "Unable to get fields");
    } catch (IllegalAccessException e) {
        Timber.e(e, "Unable to change values");
    }
}

그리고이를 proguard 구성 파일에 추가해야합니다.

-keepclassmembers class android.support.design.internal.BottomNavigationMenuView { 
    boolean mShiftingMode; 
}
-keepclassmembers class android.support.design.internal.BottomNavigationItemView { 
    int mShiftAmount;
}

안드로이드 9 (API 레벨 28) 비 SDK 인터페이스의 사용에 새로운 제한을 소개하고이 것없는 작품은 경우 28 대상 developer.android.com/about/versions/pie/...
ernestkamara

2

지원 라이브러리를 28.0.0으로 업데이트하십시오.

bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

1

support : design : 28.0.0을 사용하는 경우 BottomNavigationView에 다음 행 app : labelVisibilityMode = "unlabeled"를 추가하십시오.


0

이 메소드 위에 disableShiftMode를 추가하여 코드 아래에 추가하십시오. @SuppressLint ( "RestrictedApi")


0

https://android.jlelse.eu/disable-shift-label-animation-from-bottom-navigation-android-b42a25dcbffc

1

<com.google.android.material.bottomnavigation.BottomNavigationView
...
app:itemHorizontalTranslationEnabled="false"/>

2

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

<resources xmlns:tools="http://schemas.android.com/tools">
<dimen name="design_bottom_navigation_active_text_size"
    tools:override="true">12sp</dimen>


-1

이것을 사용하여 3-5 개의 항목에 대해 BottomNevigationView에 텍스트와 아이콘을 모두 표시하고 이동을 중지 할 수 있습니다.

 app:labelVisibilityMode="labeled"

그러나 5 항목에 대한 BottmNevigationView에서 긴 텍스트 절단 문제가 발생합니다. 이를 위해 BottomNevigationView의 아이콘뿐만 아니라 텍스트 이동을 중지하는 좋은 솔루션을 찾았습니다. BottomNevigationView의 아이콘뿐만 아니라 텍스트 이동을 중지 할 수도 있습니다. 코드 조각이 여기에 제공됩니다.

1. 아래와 같이 BottomNevigationView에이 코드를 추가하십시오.

<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. 다음과 같이 메뉴 항목을 추가하십시오.

 <?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. style.xml 파일에이 스타일을 추가하십시오.

 <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) Dimen 폴더에 추가하십시오

<?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>

링크링크 에서 도움을 받았습니다.이 링크 를 연구하여 도움을받을 수도 있습니다. 이것은 많은 도움이됩니다. 감사....

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.