development

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

big-blog 2020. 6. 24. 07:07
반응형

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


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

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

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


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

현재로서는 기존 API를 통해 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 스타일링에 대한 전체 가이드를 확인할 수 있습니다.


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

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

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

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

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

tools:override="true"

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

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

확장 기능으로 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()

나를 위해 작동

bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

또는

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

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

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

최신 정보

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

다른 사람들이 지적했듯이 지원 라이브러리 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'


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

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

BottomNavigationView xml 속성에 넣습니다.

app:itemHorizontalTranslationEnabled="false"

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

bottomNavigationView.setItemHorizontalTranslationEnabled(false);

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

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


당신의 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 하단 탐색보기 텍스트 및 이동 비활성화


I had some weird behavior with BottomNavigationView. When I was selecting any item/fragment in it, the fragment pushes BottomNavigationView a bit lower, so text of BottomNavigationView goes below the screen, so only icons were visible and text goes hidden on clicking of any item.

If you are facing that weird behavior then Here is the solution. Just remove

android:fitsSystemWindows="true"

in your root layout of fragment. Just remove this and boom! BottomNavigationView will work fine, now it can be shown with text and icon. I had this in my root CoordinatorLayout of fragment.

Also don't forget to add

BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

in your activity to disable shifting mode. Though it is not exactly related to the asked question, but still I find this helpful.


This is a third party library I use and it has many customization options like disabling shift mode, showing only icons, setting icons size, etc. BottomNavigationViewEx


To completely remove animations:

If you also want to get rid of that annoying little top margin animation, you need more reflection code. Here's the complete solution that removes any animation:

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

And make sure to add that to your proguard configuration file:

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

update your support library to 28.0.0.

bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

If you are using support:design:28.0.0 add this line app:labelVisibilityMode="unlabeled" to your BottomNavigationView


It's very simple, Just add a property in BottomNaviationView

app:labelVisibilityMode="unlabeled"

just want to add that above this method disableShiftMode add below code too. @SuppressLint("RestrictedApi")


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

참고 URL : https://stackoverflow.com/questions/40176244/how-to-disable-bottomnavigationview-shift-mode

반응형