BottomNavigationView hem simgeleri hem de metin etiketlerini her zaman görüntüler


125

Tasarım destek kitaplığı sürüm 25'ten android.support.design.widget.BottomNavigationView kullanıyorum

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

<android.support.design.widget.BottomNavigationView
        android:id="@+id/bottomBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="center"
        app:itemBackground="@color/colorPrimary"
        app:menu="@menu/bottom_navigation_main"
        android:forceHasOverlappingRendering="true"/>

@ Menu / bottom_navigation_main içinde yalnızca üç eylem olduğunda, her zaman hem simgeleri hem de metin etiketlerini görüntüler.

Üçten fazla eylem olduğunda hem simgeleri hem de metin etiketlerini her zaman görüntülemenin yolu nedir?


Bottom_navigation_main.xml menünüzde, android: showAsAction = "ifRoom" varsa bunu android olarak değiştirin: showAsAction = "her zaman" her öğe için.
Shashank Udupa

Hayır, işe yaramadı. daha önce denedim.
Android Geliştiricisi

Menü xml dosyanızı gösterebilir misiniz
Shashank Udupa

'<? xml version = "1.0" encoding = "utf-8"?> <menu xmlns: android = " schemas.android.com/apk/res/android " xmlns: app = " schemas.android.com/apk/ res-auto "> <item android: id =" @ + id / action_favorites "app: showAsAction =" always "/> <item android: id =" @ + id / action_schedules "app: showAsAction =" her zaman "/> < item android: id = "@ + id / action_music" app: showAsAction = "always" /> <item android: id = "@ + id / account" android: enabled = "true" app: showAsAction = "her zaman" /> </menu> '
Android Geliştiricisi

4
yer uygulaması: labelVisibilityMode = BottomNavigationView'da "etiketli".
Shrawan

Yanıtlar:


327

Hala bir çözüm arayan ve üçüncü taraf kitaplıklarına veya çalışma zamanı yansımasına güvenmek istemeyen herkes için, Destek Kitaplığı 28 / Jetpack'teki BottomNavigationView yerel olarak her zaman metin etiketine sahip olmayı destekler.

Bu aradığınız yöntemdir.

Veya XML'de, app:labelVisibilityMode="labeled"


hangi kütüphane sürümüne ihtiyacım var?
DaniloDeQueiroz

destek kitaplığı 28-
alpha1

Yalnızca basıldığında / odaklandığında simge metnini göstermek için görünürlük modunu "otomatik" olarak da değiştirebilirsiniz. Kod: app: labelVisibilityMode = "auto"
Kenny Dabiri

Adamsın! Teşekkürler, bu Materyal Kitaplığının en son sürümüyle çalışıyor.
sud007

68

8 MAYIS 2018 TARİHİNDEN İTİBAREN GÜNCELLEME

app:labelVisibilityMode="labeled" Doğrudan kullanabilirsiniz <android.support.design.widget.BottomNavigationView />

Kaynak: https://developer.android.com/reference/com/google/android/material/bottomnavigation/LabelVisibilityMode

Uzun çözümün altında buna ihtiyacınız yok.

ÖNCEKİ CEVAP

BottomNavigationView ile bazı garip davranışlar yaşadım. İçinde herhangi bir öğeyi / parçayı seçtiğimde, parça BottomNavigationView'ı biraz daha aşağıya iter, bu nedenle BottomNavigationView metni ekranın altına gider, böylece herhangi bir öğeye tıklandığında yalnızca simgeler görünür ve metin gizlenir.

Bu tuhaf davranışla karşı karşıyaysanız, işte çözüm. Sadece kaldır

android:fitsSystemWindows="true"

kök parça düzeninizde. Sadece bunu kaldır ve bum! BottomNavigationView iyi çalışacak, şimdi metin ve simge ile gösterilebilir. Bunu, kök Koordinatörümde parça düzeni vardı.

Ayrıca eklemeyi unutmayın

BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);

etkinliğinizde vites modunu devre dışı bırakmak için.

İşte o sınıf:

public class BottomNavigationViewHelper {

    @SuppressLint("RestrictedApi")
    public static void removeShiftMode(BottomNavigationView view) {
        //this will remove shift mode for bottom navigation 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);
                // set once again checked value, so view will be updated
                item.setChecked(item.getItemData().isChecked());
            }

        } catch (NoSuchFieldException e) {
            Log.e("ERROR NO SUCH FIELD", "Unable to get shift mode field");
        } catch (IllegalAccessException e) {
            Log.e("ERROR ILLEGAL ALG", "Unable to change value of shift mode");
        }
    }
}

Bu, STAR_ZERO'nun cevabı ile birlikte sorunumu çözdü!
Christopher Smit

Görüşmenizde disableShiftModeve sınıfta removeShiftMode. Bu küçük çelişkinin dışında cevabınız benim için sorunu çözdü. Artık kaydırmadan ve metin + simge içeren beş menü öğem var. Teşekkürler çok fazla!
Yamakuzure

Mükemmel. Alt navigasyonunuzda 3'ten fazla öğe varsa, bir değişim modu görünür. Bunu kullanarak, bu kaydırmayı devre dışı bırakabilirsiniz ve böylece metin içeren tüm simgeler aynı anda görünür.
Kişor Bikram Oli

1
Bu kısıtlanmamış api'dir ve destek kitaplığı sürüm 28. + üzerinde çalışmaz. Kabul edilen @shaishgandhi cevabı bunu yapmanın daha uygun bir yoludur.
okarakose

19

25. versiyonda zor.

Bu kodu deneyin. Ama bunun iyi bir çözüm olmadığını düşünüyorum.

BottomNavigationView navigationView = (BottomNavigationView) findViewById(R.id.bottomBar);
BottomNavigationMenuView menuView = (BottomNavigationMenuView) navigationView.getChildAt(0);
for (int i = 0; i < menuView.getChildCount(); i++) {
    BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(i);
    itemView.setShiftingMode(false);
    itemView.setChecked(false);
}

Android Studio'da şu şekilde kod eklemelisiniz: `` `// noinspection RestrictedApi itemView.setShiftingMode (false); // noinspection RestrictedApi itemView.setChecked (false); ``
Jiezhi.G

4
hala öğeleri değiştiriyor
CodeToLife

1
Mükemmel !! hem simgeyi hem de metni görüntüler. Ancak vites değiştirme modu (yanlış) çalışmıyor.
Minkoo

Bu, KishanSolanki124'ün cevabı ile birlikte sorunumu çözdü!
Christopher Smit

11

İşte @STAR_ZERO ve @ KishanSolanki124'ün çözümünü birleştiren bir Kotlin eklenti işlevi.

fun BottomNavigationView.disableShiftMode() {
    val menuView = getChildAt(0) as BottomNavigationMenuView

    menuView.javaClass.getDeclaredField("mShiftingMode").apply {
        isAccessible = true
        setBoolean(menuView, false)
        isAccessible = false
    }

    @SuppressLint("RestrictedApi")
    for (i in 0 until menuView.childCount) {
        (menuView.getChildAt(i) as BottomNavigationItemView).apply {
            setShiftingMode(false)
            setChecked(false)
        }
    }
}

Kullanmak için:

myBottomNavigation.disableShiftMode()

10

Bu etkiyi istiyor musunuz?

Resmi görmek için burayı tıklayın

Öyleyse, BottomNavigationViewEx'i denemenizi tavsiye ettim


1
Kitaplığınız iyi ve etkileyici bir çalışma Ama ben bu işlevselliği tasarım kitaplığını kullanarak elde etmek istiyordum 25.0.0 Maalesef bu android tasarım uygulamasına aykırı
Android Geliştiricisi

Belgelerdeki "Sabit alt gezinme çubuğu" na göre bu, Materyal Tasarım özelliklerine aykırı değildir . Ayrıca, bu harika kitaplığı paylaştığınız için şahsen teşekkür ederim.
Serg de Adelantado

1
Bu, Materyal Tasarım özelliklerine aykırıdır. Sağladığınız belgeyi okursanız, açıkça "Dört veya beş eylem varsa, etkin olmayan görünümleri yalnızca simge olarak görüntüleyin" dediğini göreceksiniz.
Felipe

8

Bunu BottomNevigationView'da hem metni hem de simgeleri göstermek için kullanabilirsiniz.

app:labelVisibilityMode="labeled"

Bunu kullanıyorsanız hem simgeyi hem de metni görüntüleyebileceksiniz

<android.support.design.widget.BottomNavigationView
    app:labelVisibilityMode="labeled"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/bottom_navigation_view"
    android:layout_alignParentBottom="true"
    app:menu="@menu/bottom_navigation_menu"/>

6

App: labelVisibilityMode = "labeled" öğesini doğrudan şurada kullanabilirsiniz:

<com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:labelVisibilityMode="labeled"
        android:elevation="8dp"
        android:layout_alignParentBottom="true"
        app:itemBackground="@drawable/bottom_navi"
        app:itemTextColor="@color/white"
        app:itemIconTint="@color/white"
        app:menu="@menu/bottom_nav_menu_managment" />

5

BottomNavigationView sınıfında bir BottomNavigationMenuView alanı ve BottomNavigationMenuView'da alt çubuktaki öğeler olan BottomNavigationItemView [] alanı vardır.

N öğelerin sayısı olsun, BottomNavigationMenuView BottomNavigationItemView [] dizisinin her üyesinde BottomNavigationItemView.setShiftingMode (n> 3) 'ü çağıracaktır. Bu işlev davranışa karar verir (başlığı her zaman veya sadece seçim üzerine göster).

bu yüzden başlıkları her zaman göstermenin yolu bu yöntemi çağırmaya çalışmaktır ve özel alanlara erişmek için yansımayı kullanabilirsiniz.

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


//  get the private BottomNavigationMenuView field 
        Field f = null;
        try {
            f = bottomNavigationView.getClass().getDeclaredField("mMenuView");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        f.setAccessible(true);
        BottomNavigationMenuView menuView=null;
        try {
             menuView = (BottomNavigationMenuView) f.get(bottomNavigationView); 
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

//  get the private BottomNavigationItemView[]  field 
        try {
            f=menuView.getClass().getDeclaredField("mButtons");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        f.setAccessible(true);
        BottomNavigationItemView[] mButtons=null;
        try {
            mButtons = (BottomNavigationItemView[]) f.get(menuView); 
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


        for(int i=0;i<mButtons.length;i++){
            mButtons[i].setShiftingMode(false);
            mButtons[i].setChecked(true);
        }

Bu çok iyi, sadece BottomNavigationMenuView’un da değişmediğinden emin olmalıyız. -> f = menuView.getClass (). getDeclaredField ("mShiftingMode"); f.setAccessible (doğru); f.setBoolean (menuView, false);
stephane k.

4

Başlıkları sonuna kadar göstermek için. Bu Kotlin kodunu deneyin:

@SuppressLint("RestrictedApi")
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_ofree)

    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)

    val menuView = navigation.getChildAt(0) as BottomNavigationMenuView
    for (i in 0 until menuView.childCount) {
        val itemView = menuView.getChildAt(i) as BottomNavigationItemView
        itemView.setShiftingMode(false)
        itemView.setChecked(false)
    }
}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.