BottomNavigationView ที่มีมากกว่า 3 รายการ: ชื่อแท็บซ่อนอยู่


85

ฉันใช้ BottomNavigationView โดยใช้ Android Support Desing Library 25 แต่เมื่อฉันเปลี่ยนแท็บชื่อของแท็บอื่นก็ซ่อนอยู่ แต่ไม่มีปัญหาในการซ่อนมุมมองการนำทางด้านล่างที่แท้จริง แต่ของฉันซ่อนอยู่

MyBottomNavigation

แต่ฉันอยากให้มันเป็นแบบนั้น มีความคิดที่จะทำอย่างไร ฉันขาดอะไรไป?

ActualBottomNavigation

นี่คือรหัสของฉัน:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.yunus.ototakip.MainActivity">

<FrameLayout
    android:id="@+id/main_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/bottom_navigation"
    android:layout_alignParentTop="true">
</FrameLayout>

<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    app:itemBackground="@color/colorPrimary"
    app:itemIconTint="@color/beyaz"
    app:itemTextColor="@color/beyaz"
    app:menu="@menu/bottombar_menu" />

bottom_bar_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
 <item
android:id="@+id/bb_menu_arac"
android:enabled="true"
android:icon="@drawable/icon_car"
android:title="@string/araclarim"
app:showAsAction="ifRoom" />
 <item
android:id="@+id/bb_menu_yakin"
android:enabled="true"
android:icon="@drawable/icon_yer"
android:title="@string/yakinimdakiler"
app:showAsAction="ifRoom" />
  <item
android:id="@+id/bb_menu_yaklasan"
android:enabled="true"
android:icon="@drawable/icon_takvim"
android:title="@string/yaklasanlar"
app:showAsAction="ifRoom" />

<item
    android:id="@+id/bb_menu_ipucu"
    android:enabled="true"
    android:icon="@drawable/icon_ipucu"
    android:title="@string/ipuclari"
    app:showAsAction="ifRoom" />
 </menu>

คุณได้ลองapp:showAsAction="alwaysแทนหรือไม่ifRoom
Yassine BELDI

ฉันพยายามแล้ว แต่มันก็ยังซ่อนอยู่
Yunus Haznedar


1
@YunusHaznedar ถ้ารายการมากกว่า 3 ข้อความจะซ่อนอยู่เสมอ ...
Shashank Verma

1
สวัสดี @DanXPrado ขอบคุณสำหรับการแบ่งปันวิธีแก้ปัญหา ฉันได้ทำเครื่องหมายคำตอบของคุณว่ายอมรับแล้ว มีความสุขในการเขียนโค้ด
Yunus Haznedar

คำตอบ:


143

วิธีแก้ปัญหาโดยใช้การสะท้อนกลับไม่ทำงานอีกต่อไปเนื่องจากฟิลด์ mShiftingMode ถูกลบออก

มีวิธีง่ายๆในการดำเนินการตอนนี้: ใช้ Support Library 28 หรือสูงกว่าและเพิ่มapp:labelVisibilityMode="labeled"ในBottomNavigationViewการประกาศ XML ของคุณ

หวังว่าจะช่วยได้


ทำงานเหมือนแชมป์ แต่จะทำให้เลื่อนเป็นวงกลมได้อย่างไร?
Shailendra Madda

@ShylendraMadda ฉันแนะนำให้คุณโพสต์เป็นคำถามใหม่เนื่องจากไม่เกี่ยวข้องกับคำถามนี้
Danilo Prado

1
นี่ไม่ใช่พฤติกรรมเริ่มต้นอย่างไร ... ฉันเสียเวลาไปสองสามชั่วโมงกับแอพ: showAsAction, android: visible, android: เปิดใช้งานและแฮ็กอื่น ๆ อีกมากมาย ขอบคุณ!
ข่านเดนมาร์ก

94

อัปเดต

removeShiftMode ()ไม่จำเป็นอีกต่อไปเนื่องจากในไลบรารีสนับสนุน 28.0.0-alpha1 เราสามารถเพิ่มLabelsได้แล้ว

ใน XML:

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

สำหรับการเปลี่ยนแปลงทางโปรแกรม:

mBottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); 

เพื่อให้ได้ผล: อัปเดตไลบรารีสนับสนุนการออกแบบเป็น 28.0.0-alpha1

นี่คือการอ่านที่ดี

สำหรับห้องสมุดสนับสนุนรุ่นเก่า:

ใน. bottom_bar_menu.xmlเปลี่ยนshowAsActionแอตทริบิวต์

<item android:id="@id/menu_item"
android:title="text"
android:icon="@drawable/drawable_resource_name"
android:showAsAction="always|withText" />

ใน build.gradle:

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

การนำทางด้านล่างดูมากกว่า 3 รายการ: ใช้removeShiftMode()วิธีการ

ในการBottomNavigationViewHelper.javaใช้งาน:

import android.annotation.SuppressLint;
import android.support.design.internal.BottomNavigationItemView;
import android.support.design.internal.BottomNavigationMenuView;
import android.support.design.widget.BottomNavigationView;
import java.lang.reflect.Field;

    public class BottomNavigationViewHelper {
        @SuppressLint("RestrictedApi")
        public static void removeShiftMode(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("BottomNav", "Unable to get shift mode field", e);
            } catch (IllegalAccessException e) {
                Log.e("BottomNav", "Unable to change value of shift mode", e);
            }
        }
    }

เรียกโดยใช้:

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

มันจะปิดการเคลื่อนไหว shift ของข้อความชื่อเรื่องและเปิดใช้งานข้อความที่จะแสดง


2
ไม่มันยังคงซ่อนตัวอยู่ ฉันพยายาม "always" และ "always | withText"
Yunus Haznedar

1
ชื่อรายการของคุณมีขนาดใหญ่ทำให้มุมมองของผู้อื่นบล็อกหรือไม่ ลองใช้ชื่อเรื่องขนาดเล็กและภาพที่วาดได้ ..
rafsanahmad007

1
ดูบรรทัดนี้ในการสอนที่คุณกำลังติดตามIt’s important to note that the maximum number of items we can display is 5. This may change at any point, so it’s important to check this by using the getMaxItem() method provided by the BottomNavigationView class rather than hard-coding the value yourself.
rafsanahmad007

1
คำตอบที่ดีขอบคุณ
Hamza Abdullah

2
โซลูชันการสะท้อนกลับใช้งานได้ดีcom.android.support:design:25.4.0แต่ล้มเหลวcom.android.support:design:26.1.0ดังนั้นฉันจึงย้อนกลับ SDK เป้าหมายและเวอร์ชันอ้างอิงเล็กน้อย
Evi Song

10

หลังจากสแกนซอร์สโค้ดของ BottomNavigationView ฉันพบ

mShiftingMode = mMenu.size() > 3;

ในBottomNavigationMenuView.javaบรรทัด 265 หมายความว่าในขณะที่ขนาดเมนูมากกว่า 3 ชื่อแท็บจะถูกซ่อน ดังนั้นหากคุณต้องการแสดงชื่อแท็บคุณเพียงแค่ต้องรับโค้ดจากบิลด์และเปลี่ยนเป็นด้านล่าง

mShiftingMode = mMenu.size() > 5;

PS: จำนวนแท็บสูงสุด BottonNavigationView ต้องอยู่ระหว่าง 3 ถึง 5 คุณจะได้รับโค้ดบนBottomNavigationViewNew ใส่คำอธิบายภาพที่นี่


ฉันมี CustomBottomView ของตัวเองที่ขยาย BottomNavigationView มีวิธีตั้งค่าคุณสมบัตินั้นแทนหรือไม่
JPM

1
ฉันไม่เห็นบรรทัด "BottomNavigationMenuView" ที่เกี่ยวกับขีด จำกัด 3 แท็บ อาจจะมีการเปลี่ยนแปลงรหัส?
นักพัฒนา Android

8

สร้าง Class BottomNavigationViewHelper

import android.annotation.SuppressLint;
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 {
    @SuppressLint("RestrictedApi")
    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);
if(menuView.getChildCount()<6)
           {
            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);
        }
    }
}   

โทร

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

1
มี SuppressLint ซึ่งแก้ปัญหาการแจ้งเตือนข้อ จำกัด API
code4j

3

ฟังก์ชั่นขยาย Kotlin:

@SuppressLint("RestrictedApi")
fun BottomNavigationView.removeShiftMode(){
    val menuView = this.getChildAt(0) as BottomNavigationMenuView
    try {
        val shiftingMode = menuView.javaClass.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) {
        e.printStackTrace()
        Timber.tag("BottomNav").e( e, "Unable to get shift mode field")
    } catch (e: IllegalAccessException) {
        Timber.tag("BottomNav").e( e, "Unable to change value of shift mode")
    }
}

ขอบคุณครับ. ชื่นชมมาก.
Yunus Haznedar

1
item.setShiftingMode(false)ตอนนี้item.setShifting(false)
Sim

2

ฉันใช้คำตอบ rafsanahmad007 ค่อนข้างมากแต่แปลเป็น Kotlin ให้ฉันแบ่งปันสำหรับผู้หลงทางในอนาคต

@SuppressLint("RestrictedApi")
fun BottomNavigationView.disableShiftMode() {
    val menuView = this.getChildAt(0) as BottomNavigationMenuView
    try {
        val shiftingMode = menuView::class.java.getDeclaredField("mShiftingMode")
        shiftingMode.setAccessible(true)
        shiftingMode.setBoolean(menuView, false)
        shiftingMode.setAccessible(false)
        for (i in 0..(menuView.childCount - 1)) {
            val item = menuView.getChildAt(i) as BottomNavigationItemView
            item.setShiftingMode(false)
            // set once again checked value, so view will be updated
            item.setChecked(item.getItemData().isChecked())
        }
    } catch (e: NoSuchFieldException) {
        Timber.e("Unable to get shift mode field")
    } catch (e: IllegalAccessException) {
        Timber.e("Unable to change value of shift mode")
    }
}

1
วิธีการแก้ปัญหานี้ใช้ไม่ได้อีกต่อไปวิธีแก้ปัญหาที่ยอมรับนั้นถูกต้องโดย @DanXPrado
jpardogo

ขอบคุณที่แจ้งให้เราทราบ
Karma Maker

1

สิ่งหนึ่งที่ควรทราบแม้ว่าจะไม่มีผลในกรณีนี้

รูปแบบนี้สามารถใช้ได้เมื่อคุณมีจุดหมายปลายทางระดับบนสุดระหว่าง 3 ถึง 5 แห่งที่จะนำทางไป

ในการเปิดใช้ชื่อไอคอนเพื่อแสดงให้ทำดังต่อไปนี้:

  1. ตรวจสอบให้แน่ใจว่าเมนู XML รายการ (bottom_navigation_menu) ของคุณมีโครงสร้างดังนี้: -

    <item
        android:id="@+id/action_home"
        android:enabled="true"
        android:icon="@drawable/ic_action_home"
        android:title="HOME"
        app:showAsAction="ifRoom"/>
    
    <item
        android:id="@+id/action_favourites"
        android:enabled="true"
        android:icon="@drawable/ic_action_favourite"
        android:title="FAVOURITES"
        app:showAsAction="ifRoom"/>
    
    <item
        android:id="@+id/action_basket"
        android:enabled="true"
        android:icon="@drawable/ic_action_basket"
        android:title="BASKET"
        app:showAsAction="ifRoom"/>
    

  2. เพิ่มสิ่งต่อไปนี้ในแอปโค้ดBottomNavigationView: labelVisibilityMode = "labelled"

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:background="@android:color/white"
    app:itemIconTint="@android:color/black"
    app:itemTextColor="@android:color/black"
    app:menu="@menu/bottom_navigation_menu"
    app:labelVisibilityMode="labeled"/>


0

สิ่งนี้ใช้ได้กับฉันใน API 26:

 navigation = (BottomNavigationView) view.findViewById(R.id.bottom_navigation);


     try{disableShiftMode(navigation);}catch(Exception ew){}

ใช้วิธีนี้ในกิจกรรมหรือ Fragment ของคุณที่คุณต้องการเรียก:

 @SuppressLint("RestrictedApi")
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);
            item.setShiftingMode(false);

            item.setChecked(item.getItemData().isChecked());
        }
    } catch (NoSuchFieldException e) {

    } catch (IllegalAccessException e) {

    }
}

0

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

 app:labelVisibilityMode="labeled"

แต่คุณจะประสบปัญหาการตัดข้อความยาว ๆ บน BottmNevigationView จำนวน 5 รายการ สำหรับสิ่งนั้นฉันพบวิธีแก้ปัญหาที่ดีสำหรับการหยุดการเปลี่ยนข้อความและไอคอนของ 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>

ผมได้รับความช่วยเหลือจากเหล่านี้ เชื่อมโยงและการเชื่อมโยงนอกจากนี้คุณยังจะได้รับได้รับความช่วยเหลือโดยการศึกษา links.This เหล่านี้ช่วยให้ผม lot.Hope นี้ยังช่วยให้คุณ ขอบคุณ ....


0

แก้ไขอย่างรวดเร็วเพียงเพิ่ม app: labelVisibilityMode = "ป้ายกำกับ" ใน xml

<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    app:itemBackground="@color/colorPrimary"
    app:itemIconTint="@drawable/bottom_navigation_color_selector"
    app:itemTextColor="@drawable/bottom_navigation_color_selector"
    app:labelVisibilityMode="labeled"
    app:menu="@menu/menu_bottom_navigation" />

บันทึก

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