BottomNavigationView แสดงทั้งไอคอนและป้ายข้อความตลอดเวลา


125

ฉันใช้ android.support.design.widget.BottomNavigationView จากไลบรารีสนับสนุนการออกแบบเวอร์ชัน 25

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 จะแสดงทั้งไอคอนและป้ายข้อความตลอดเวลา

วิธีใดในการแสดงทั้งไอคอนและป้ายข้อความตลอดเวลาเมื่อมีการกระทำมากกว่าสามรายการ


ในเมนู bottom_navigation_main.xml ของคุณหากคุณมี android: showAsAction = "ifRoom" ให้เปลี่ยนเป็น android: showAsAction = "always" สำหรับแต่ละรายการ
Shashank Udupa

ไม่มันไม่ได้ผล ฉันเคยลองมาก่อน
นักพัฒนา Android

คุณสามารถแสดงไฟล์ xml เมนูของคุณได้ไหม
Shashank Udupa

'<? xml version = "1.0" encoding = "utf-8"?> <เมนู 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 =" always "/> < item android: id = "@ + id / action_music" app: showAsAction = "always" /> <item android: id = "@ + id / account" android: enable = "true" app: showAsAction = "always" /> </menu> '
นักพัฒนา Android

4
place app: labelVisibilityMode = "ป้ายกำกับ" ใน BottomNavigationView
Shrawan

คำตอบ:


327

สำหรับใครก็ตามที่ยังคงมองหาวิธีแก้ปัญหาและไม่ต้องการพึ่งพาไลบรารีของบุคคลที่สามหรือการสะท้อนรันไทม์ BottomNavigationView ใน Support Library 28 / Jetpack รองรับการมีป้ายข้อความเสมอ

นี่คือวิธีที่คุณกำลังมองหา

หรือใน XML app:labelVisibilityMode="labeled"


ฉันต้องการไลบรารีเวอร์ชันใด
DaniloDeQueiroz

สนับสนุนไลบรารี 28-alpha1 +
shaishgandhi

คุณยังสามารถเปลี่ยนโหมดการมองเห็นเป็น "อัตโนมัติ" เพื่อแสดงข้อความไอคอนเมื่อกด / โฟกัสเท่านั้น รหัส: app: labelVisibilityMode = "auto"
Kenny Dabiri

คุณคือผู้ชาย! ขอบคุณสิ่งนี้ใช้ได้กับไลบรารีวัสดุเวอร์ชันล่าสุด
sud007

68

อัปเดตตั้งแต่วันที่ 8 พฤษภาคม 2561

คุณสามารถใช้ app:labelVisibilityMode="labeled" โดยตรงใน<android.support.design.widget.BottomNavigationView />

ที่มา: https://developer.android.com/reference/com/google/android/material/bottomnavigation/LabelVisibilityMode

ไม่ต้องการวิธีแก้ปัญหาที่ยาวด้านล่างนี้

คำตอบก่อนหน้านี้

ฉันมีพฤติกรรมแปลก ๆ กับ BottomNavigationView เมื่อฉันเลือกรายการ / ส่วนใดส่วนหนึ่งในนั้นส่วนจะกด BottomNavigationView ให้ต่ำลงเล็กน้อยดังนั้นข้อความของ BottomNavigationView จะอยู่ด้านล่างของหน้าจอดังนั้นจึงมีเพียงไอคอนเท่านั้นที่มองเห็นได้และข้อความจะถูกซ่อนเมื่อคลิกที่รายการใด ๆ

หากคุณกำลังเผชิญกับพฤติกรรมแปลก ๆ นี่คือวิธีแก้ปัญหา เพียงแค่ลบ

android:fitsSystemWindows="true"

ในเค้าโครงรากของส่วนย่อยของคุณ เอาแค่นี้ก็บูม! BottomNavigationView จะทำงานได้ดีตอนนี้สามารถแสดงด้วยข้อความและไอคอน ฉันมีสิ่งนี้ในผู้ประสานงานรากของฉันเค้าโครงของส่วน

อย่าลืมเพิ่ม

BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);

ในกิจกรรมของคุณเพื่อปิดใช้งานโหมดการเปลี่ยนเกียร์

นี่คือคลาสนั้น:

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

สิ่งนี้ร่วมกับคำตอบของ STAR_ZERO ช่วยแก้ปัญหาของฉันได้!
Christopher Smit

ในการเรียกที่คุณมีและในชั้นเรียนdisableShiftMode removeShiftModeนอกเหนือจากความคลาดเคลื่อนเล็กน้อยคำตอบของคุณยังช่วยแก้ปัญหาให้ฉันได้ ตอนนี้ฉันมีห้าเมนูโดยไม่ต้องขยับและมีไอคอนข้อความ + ขอบคุณมากมาก!
Yamakuzure

สมบูรณ์ เมื่อคุณมีมากกว่า 3 รายการในการนำทางด้านล่างของคุณมากกว่า 3 รายการจะมีโหมดเปลี่ยนเกียร์ เมื่อใช้สิ่งนี้คุณสามารถปิดใช้งานการขยับนั้นและด้วยเหตุนี้ไอคอนทั้งหมดที่มีข้อความจึงปรากฏขึ้นพร้อมกัน
Kishor Bikram Oli

1
นี่เป็น API ที่ไม่ จำกัด และใช้ไม่ได้กับไลบรารีที่รองรับเวอร์ชัน 28 + คำตอบของ @shaishgandhi ที่ได้รับการยอมรับเป็นวิธีที่เหมาะสมกว่าในการทำ
okarakose

19

เป็นเรื่องยากในรุ่น 25

ลองใช้รหัสนี้ แต่ฉันคิดว่ามันไม่ใช่ทางออกที่ดี

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 ควรเพิ่มโค้ดดังนี้: `` // noinspection RestrictedApi itemView.setShiftingMode (false); // noinspection RestrictedApi itemView.setChecked (false); ``
Jiezhi.G

4
มันยังคงเปลี่ยนรายการ
CodeToLife

1
เป๊ะ !! แสดงทั้งไอคอนและข้อความ แต่โหมดเปลี่ยนเกียร์ (เท็จ) ไม่ทำงาน
Minkoo

สิ่งนี้ร่วมกับคำตอบของ KishanSolanki124 ช่วยแก้ปัญหาของฉันได้!
Christopher Smit

11

นี่คือฟังก์ชันส่วนขยายของ Kotlin ที่รวมโซลูชันของ @STAR_ZERO และ @ KishanSolanki124

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

วิธีใช้:

myBottomNavigation.disableShiftMode()

10

คุณต้องการเอฟเฟกต์นี้หรือไม่?

คลิกที่นี่เพื่อดูภาพ

ถ้าเป็นเช่นนั้นฉันขอแนะนำให้คุณลองใช้BottomNavigationViewEx


1
ห้องสมุดของคุณเป็นงานที่ดีและน่าประทับใจ แต่ฉันต้องการบรรลุฟังก์ชันนี้โดยใช้ไลบรารีการออกแบบ 25.0.0 แต่น่าเสียดายที่มันขัดต่อแนวทางปฏิบัติในการออกแบบของ
Android

นี่คือไม่ได้กับรายละเอียดการออกแบบวัสดุตามที่ "คงที่แถบนำทางด้านล่าง" ในเอกสาร นอกจากนี้ขอขอบคุณส่วนตัวสำหรับการแบ่งปันห้องสมุดที่ยอดเยี่ยมนี้
Serg de Adelantado

1
สิ่งนี้ขัดต่อข้อกำหนดการออกแบบวัสดุ หากคุณอ่านเอกสารที่คุณให้มาคุณจะเห็นว่ามีข้อความชัดเจนว่า "หากมีการดำเนินการสี่หรือห้ารายการให้แสดงมุมมองที่ไม่ใช้งานเป็นไอคอนเท่านั้น"
Felipe

8

คุณสามารถใช้สิ่งนี้เพื่อแสดงทั้งข้อความและไอคอนบน BottomNevigationView

app:labelVisibilityMode="labeled"

หากคุณใช้สิ่งนี้คุณจะสามารถดูทั้งไอคอนและข้อความ

<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 = "ป้ายกำกับ" โดยตรงใน

<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 จะมีฟิลด์ BottomNavigationMenuView และใน BottomNavigationMenuView จะมีฟิลด์ BottomNavigationItemView [] ซึ่งเป็นรายการในแถบด้านล่าง

สมมติว่า n คือจำนวนรายการ BottomNavigationMenuView จะเรียก BottomNavigationItemView.setShiftingMode (n> 3) ในแต่ละสมาชิกของอาร์เรย์ BottomNavigationItemView [] ฟังก์ชันนี้จะตัดสินพฤติกรรม (แสดงชื่อเรื่องเสมอหรือเมื่อเลือกเท่านั้น)

ดังนั้นวิธีที่จะแสดงชื่อเรื่องเสมอคือพยายามเรียกวิธีนี้และคุณสามารถใช้การสะท้อนเพื่อเข้าถึงช่องส่วนตัวได้

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

นี่เป็นสิ่งที่ดีมากเพียงแค่เราต้องแน่ใจว่า BottomNavigationMenuView จะไม่เปลี่ยนไปด้วย -> f = menuView.getClass (). getDeclaredField ("mShiftingMode"); f.setAccessible (จริง); ฉ setBoolean (menuView, false);
stephane k.

4

เพื่อแสดงชื่อตลอดทาง ลองใช้รหัส Kotlin นี้:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.