Bagaimana cara menonaktifkan mode shift BottomNavigationView?

146

BottomNavigationView tidak menampilkan judul menu yang tidak aktif.

Bagaimana cara menunjukkan judul semua elemen menu di bottomNavigationBar? Masalahnya adalah bahwa dalam kasus saya hanya ditampilkan judul elemen yang diklik.

masukkan deskripsi gambar di sini

Natan Rubinstein
sumber
1
Kemungkinan duplikat bilah Navigasi Bawah Android baru
Radhey
Berikut jawaban berguna jika Anda ingin benar-benar menghapus setiap animasi: stackoverflow.com/a/51052247/2352699
Fred Porciuncula

Jawaban:

330

Implementasi BottomNavigationViewmemiliki kondisi: ketika ada lebih dari 3 item maka gunakan mode shift.

Pada saat ini Anda tidak dapat mengubahnya melalui API yang ada dan satu-satunya cara untuk menonaktifkan mode shift adalah dengan menggunakan refleksi.

Anda membutuhkan kelas pembantu:

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

Dan kemudian menerapkan disableShiftModemetode pada Anda BottomNavigationView, tetapi ingat jika Anda menggembungkan tampilan menu dari kode Anda, Anda harus menjalankannya setelah menggembungkan.

Contoh penggunaan:

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

PS.

Ingat, Anda harus menjalankan metode ini setiap kali Anda mengubah item menu di menu Anda BottomNavigationView.

MEMPERBARUI

Anda juga perlu memperbarui file konfigurasi proguard (mis. Proguard-rules.pro), kode di atas menggunakan refleksi dan tidak akan berfungsi jika proguard mengaburkan mShiftingModebidang.

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

Terima kasih Muhammad Alfaifi untuk menunjukkan masalah ini dan memberikan cuplikan .

PEMBARUAN 2

Seperti yang Jolanda Verhoef tunjukkan perpustakaan Support baru ( 28.0.0-alpha1) dan juga perpustakaan Material Components baru ( 1.0.0-beta01) menawarkan properti publik yang dapat digunakan untuk memanipulasi mode pemindahan di atas 3 item menu.

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

Di pustaka Komponen Material itu juga berlaku jika ada 5 item menu.

PEMBARUAN 3

Seperti yang ditunjukkan oleh @ThomasSunderland, Anda dapat mengatur properti ini menjadi false app:itemHorizontalTranslation="false"tanpa Enabledpostfix untuk menonaktifkan pemindahan animasi.

Anda dapat memeriksa panduan lengkap untuk menata Navigasi Bawah Laut di sini

Przemysław Piechota. kibao
sumber
10
**** Proguard :(
Muhammad Alfaifi
17
Bidang ini akan dikaburkan sehingga tidak ada cara untuk mengubah nilainya kecuali Anda mengecualikannya dalam file aturan proguard Anda
Muhammad Alfaifi
8
-keepclassmembers kelas android.support.design.internal.BottomNavigationMenuView {boolean mShiftingMode; }
Muhammad Alfaifi
8
Terkadang, saya benar-benar bertanya-tanya mengapa Google memaksa melihat implementasi pada pengembang. Meskipun ada 4 opsi di aplikasi Google+ itu sendiri, fitur sederhana ini seharusnya dapat diakses melalui fungsi sederhana jika tersedia! Masalah serupa ada di sana dengan TabLayout yang diperbaiki banyak kemudian di perpustakaan dukungan. Terima kasih atas solusinya dengan Original Replier dan @MuhammadAlfaifi untuk meningkatkan ini.
sud007
19
Perpustakaan dukungan baru (28.0.0-alpha1) mendukung perubahan perilaku ini melalui aplikasi: labelVisibilityMode = "labeled"
Jolanda Verhoef
50

Karena perpustakaan dukungan 28.0.0-alpha1:

<android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />
Junbin Deng
sumber
1
Saya menggunakan versi perpustakaan dukungan ini tetapi masih mendapatkan kesalahan pada "labelVisibilityMode" tidak ditemukan.
Sagar Maiyad
1
Bekerja dengan baik. Tidak perlu pergi untuk refleksi. Terima kasih banyak
Bhupesh
1
@Riser pastikan Anda menggunakan app:tidakandroid:
Carson Holzheimer
28

Untuk menonaktifkan animasi teks, Anda juga dapat menggunakan ini di file dimens.xml Anda:

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

Anda mungkin juga perlu menambahkan ini dalam manifes Anda:

tools:override="true"
Pafoid
sumber
tidak bekerja Saya yakin saya harus menambahkan ini di /values/dimens.xml?
Rohan Kandwal
10
@RohanKandwal perlu menambahkantools:override="true"
Boy
@ Boy Terima kasih, akan mencobanya.
Rohan Kandwal
hanya mengubah ukuran teks.
The Dude
Saya hanya perlu meletakkan seperti ini pada file dimens.xml saya:<dimen name="design_bottom_navigation_active_text_size" tools:ignore="PrivateResource">12sp</dimen>
Fernando Barbosa
22

Anda sekarang dapat menggunakan app:labelVisibilityMode="[labeled, unlabeled, selected, auto]"di28-alpha

  • labeled akan membuat semua label terlihat.
  • unlabeled hanya akan menampilkan ikon.
  • selected hanya akan menampilkan label untuk item yang dipilih dan menggeser item.
  • autoakan memilih berlabel atau dipilih berdasarkan jumlah item yang Anda miliki. berlabel 1-3 item dan dipilih untuk 3+ item.
Aidan Laing
sumber
1
terima kasih Lunkie! Ini adalah solusi terbaik dan termudah bagi saya
Gregriggins36
Di mana menambahkan baris kode ini. Saya mencoba menambahkan tetapi ada kesalahan yang tidak ditemukan.
Abdulwahid
@Abdulwahid Anda dapat menambahkan ini di xml dari bilah navigasi bawah setelah Anda memiliki perpustakaan dukungan 28 atau lebih tinggi
Aidan Laing
@Lunkie terima kasih sekarang jelas sekali mendukung perpustakaan 28
Abdulwahid
17

Jawaban Przemysław di Kotlin sebagai fungsi ekstensi

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

Penggunaan (dengan Ekstensi Android Kotlin):

bottom_navigation_view.disableShiftMode()
ElegyD
sumber
Bekerja untuk kotlin. mengapa kita perlu menggunakan anotasi ini @SuppressLint ("RestrictedApi") dapatkah Anda menjelaskan pls?
Ranjith Kumar
11

Bekerja untukku

bottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

atau

<android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled" />
UgAr0FF
sumber
saya bekerja dengan baik sampai target = 27 tetapi dari target = 28, itu rusak, teks tidak lagi ditampilkan. Tapi setLabelVisibilityMode melakukan trik untuk saya, sekarang berfungsi seperti pesona
joke4me
10

Untuk menonaktifkan animasi teks dan mengurangi ukuran font gunakan ini di file dimens.xml Anda:

<dimen name="design_bottom_navigation_text_size">10sp</dimen> 
<dimen name="design_bottom_navigation_active_text_size">10sp</dimen>
Abhishek
sumber
Satu dapat Navigate-> File...> design_bottom_navigation_item.xmluntuk melihat bahwa tidak ada cara lain.
arekolek
6

MEMPERBARUI

di Android SDK versi 28 dan di atas mereka telah berubah item.setShiftingMode(false)menjadiitem.setShifting(false)

Mereka juga menghapus bidang mShiftingMode

Jadi penggunaannya akan

 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());
        }
    }
}
Narek Hayrapetyan
sumber
Anda dapat menggunakan kode ini di bawah ini. @SuppressLint ( "RestrictedApi") menyenangkan removeShiftMode (lihat: BottomNavigationView) {val T'pilan menu = view.getChildAt (0) sebagai BottomNavigationMenuView menuView.labelVisibilityMode = LabelVisibilityMode.LABEL_VISIBILITY_LABELED menuView.buildMenuView ()}
Jauh P
5

Seperti yang orang lain tunjukkan, karena pustaka dukungan 28.0.0-alpha1 dimungkinkan:

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

atau Anda dapat mengaturnya secara terprogram .

Catatan: jika Anda meningkatkan dari pustaka dukungan versi yang lebih lama, jangan lupa untuk meningkatkan kompilasi versi SDK. Periksa versi pustaka dukungan di sini: Versi Pustaka Dukungan

Namun, Anda mungkin masih mendapatkan labelVisibilityMode tidak ditemukan pesan saat dikompilasi, jika aplikasi Anda bergantung pada versi yang lebih lama dari perpustakaan dukungan desain. Jika ini masalahnya, cobalah untuk memutakhirkan ke versi ketergantungan yang diberikan, yang setidaknya tergantung pada versi 28.0.0-alpha1 dari perpustakaan dukungan desain. Jika itu tidak memungkinkan, tentukan ketergantungan secara eksplisit.

Jika Anda menggunakan Gradle

  1. Anda dapat memeriksa ketergantungan Anda dengan menjalankan tugas dependensi dan mencari nomor versi com.android.support:design .
  2. Untuk menambahkan ketergantungan dukungan desain secara eksplisit di build.gradle Anda :

    implementasi 'com.android.support:design:28.0.0'

Richárd Bogdán
sumber
4

Untuk jawaban yang diperbarui menggunakan default. Perbarui ke perpustakaan desain terbaru

implementasi "com.android.support:design:28.0.0"

dan dimasukkan ke atribut xml BottomNavigationView Anda

app:itemHorizontalTranslationEnabled="false"

Anda dapat menempatkannya juga secara terprogram

bottomNavigationView.setItemHorizontalTranslationEnabled(false);

Anda dapat menemukan sumber di sini BottomNavigationView

Semoga ini bisa membantu Anda.

Lester L.
sumber
Apa bedanya ini app:labelVisibilityMode?
wonsuc
@wonsuc ini tentang animasi ikon dan teks yang dipilih oleh item yang dipilih. Sementara labelVisibilityMode adalah untuk menampilkan apakah Anda ingin menampilkan ikon dengan teks, atau hanya ikon yang akan ditampilkan ketika dipilih.
Lester L.
3

Untuk BottomNavigationViewadd Andaapp: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>

yang menghasilkan sebagai berikut

Navigasi Bawah Android Lihat Nonaktifkan Teks dan Shift

Semuanya
sumber
3

Ini sangat sederhana, Cukup tambahkan properti di BottomNaviationView

app:labelVisibilityMode="unlabeled"
Nevil Ghelani
sumber
2

Saya memiliki beberapa perilaku aneh dengan BottomNavigationView. Ketika saya memilih item / fragmen di dalamnya, fragmen mendorong BottomNavigationView sedikit lebih rendah, sehingga teks BottomNavigationView berada di bawah layar, jadi hanya ikon yang terlihat dan teks menjadi tersembunyi saat mengklik item apa pun.

Jika Anda menghadapi perilaku aneh itu di sini adalah solusinya. Hapus saja

android:fitsSystemWindows="true"

dalam tata letak akar fragmen Anda. Hapus ini dan booming! BottomNavigationView akan berfungsi dengan baik, sekarang dapat ditampilkan dengan teks dan ikon. Saya punya ini di root CoordinatorLayout of fragmen.

Juga jangan lupa untuk menambahkan

BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

dalam aktivitas Anda untuk menonaktifkan mode pemindahan. Meskipun tidak persis terkait dengan pertanyaan yang diajukan, tetapi saya tetap merasa ini bermanfaat.

Kishan Solanki
sumber
1
@ abbath0767 Anda sudah melihat tautan ini? Mungkin bermanfaat bagi Anda.
Kishan Solanki
Saya pikir saya sudah mencoba semuanya, terima kasih banyak, tidak berharap untuk langsung menemukan jawaban yang saya cari.
BekaBot
1
Pleasure @BekaBot
Kishan Solanki
2

Ini adalah perpustakaan pihak ketiga yang saya gunakan dan memiliki banyak opsi penyesuaian seperti menonaktifkan mode shift, hanya menampilkan ikon, mengatur ukuran ikon, dll. BottomNavigationViewEx

Pei
sumber
2

Untuk menghapus animasi sepenuhnya:

Jika Anda juga ingin menghilangkan animasi margin atas yang sedikit mengganggu itu, Anda perlu lebih banyak kode refleksi. Inilah solusi lengkap yang menghilangkan animasi apa pun:

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

Dan pastikan untuk menambahkannya ke file konfigurasi proguard Anda:

-keepclassmembers class android.support.design.internal.BottomNavigationMenuView { 
    boolean mShiftingMode; 
}
-keepclassmembers class android.support.design.internal.BottomNavigationItemView { 
    int mShiftAmount;
}
Fred Porciúncula
sumber
Android 9 (API level 28) memperkenalkan batasan baru tentang penggunaan antarmuka non-SDK dan ini tidak akan berfungsi jika menargetkan 28. developer.android.com/about/versions/pie/…
ernestkamara
2

perbarui perpustakaan dukungan Anda ke 28.0.0.

bottomNav.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
M Moersalin
sumber
1

Jika Anda menggunakan dukungan: desain: 28.0.0 tambahkan aplikasi baris ini: labelVisibilityMode = "tidak berlabel" ke BottomNavigationView Anda

Omar Hassan
sumber
0

hanya ingin menambahkan bahwa di atas metode ini disableShiftMode tambahkan kode di bawah ini juga. @SuppressLint ("RestrictedApi")

Aleesha Kanwal
sumber
-1

Anda dapat menggunakan ini untuk menampilkan teks dan ikon di BottomNevigationView untuk 3 hingga 5 item dan berhenti bergeser.

 app:labelVisibilityMode="labeled"

Tetapi Anda akan menghadapi masalah pemotongan teks panjang di BottmNevigationView untuk 5 item. untuk itu, saya menemukan solusi yang baik untuk menghentikan pergeseran teks serta ikon BottomNevigationView. Anda juga dapat berhenti menggeser teks dan juga Ikon di BottomNevigationView. Cuplikan kode diberikan di sini.

1. Tambahkan ini beberapa baris kode di BottomNevigationView seperti yang ditunjukkan

<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. Tambahkan Item Menu seperti sebagai berikut: -

 <?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. Tambahkan gaya ini dalam file 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) Tambahkan ini dalam folder 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>

Saya mendapat bantuan dari tautan dan tautan ini . Anda juga bisa mendapatkan bantuan dengan mempelajari tautan - tautan ini . Ini banyak membantu saya. Semoga ini juga membantu Anda. Terima kasih....

Rahul Kushwaha
sumber