web-dev-qa-db-fra.com

Afficher le badge en haut de l'icône de la barre de navigation inférieure

J'ai implémenté la vue de navigation du bas dans mon application et j'ai cherché partout pour afficher des badges au-dessus des icônes, par exemple this Je me demandais si cela était possible. Toute aide est appréciée. Je vous remercie.

54
heisenberg91

Lorsque vous utilisez la barre de navigation inférieure de la bibliothèque de support, il est assez complexe d'afficher un badge/une notification sur les éléments de menu. Cependant, il existe des solutions faciles pour y arriver. Tels que https://github.com/aurelhubert/ahbottomnavigation

Cette bibliothèque est une version plus avancée de la barre de navigation inférieure. Et vous pouvez définir un badge sur un élément de menu en utilisant simplement cet extrait de code.

bottomNavigation.setNotification(notification, bottomNavigation.getItemsCount() - 1);

Et vous aurez le résultat suivant

enter image description here

27
Noman Rafique

Si vous voulez juste utiliser un stock BottomNavigationView et aucune bibliothèque tierce, voici comment je l'ai fait:

BottomNavigationMenuView bottomNavigationMenuView =
            (BottomNavigationMenuView) navigationView.getChildAt(0);
View v = bottomNavigationMenuView.getChildAt(3); 
BottomNavigationItemView itemView = (BottomNavigationItemView) v;

View badge = LayoutInflater.from(this)
            .inflate(R.layout.notification_badge, itemView, true);

Ensuite, voici le fichier de mise en page:

<merge xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools">

    <TextView
        Android:id="@+id/notifications.badge"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="top|center_horizontal"
        Android:layout_marginLeft="10dp"
        Android:layout_marginStart="10dp"
        Android:background="@drawable/notification_badge"
        Android:gravity="center"
        Android:padding="3dp"
        Android:text="9+"
        Android:textColor="@color/white"
        Android:textSize="11sp" />
</merge>

Ensuite, il suffit de trouver TextView par id et de définir le texte. @drawable/notification_badge est juste une forme de cercle dessinable

136
Tinashe

L'ajout de badges est pris en charge de manière native, à l'aide de la dernière dépendance de matériel, ajoutez ceci à votre build.gradle.

    implementation 'com.google.Android.material:material:1.1.0-alpha09'

dans votre mise en page ajoutez ceci

<!-- The rest of your layout here ....-->

  <com.google.Android.material.bottomnavigation.BottomNavigationView
            Android:id="@+id/bottom_navigation"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            app:menu="@menu/bottom_nav_menu"
            />

alors vous pouvez juste

     val navBar  = findViewById<BottomNavigationView>(R.id.bottom_navigation)
     navBar.getOrCreateBadge(R.id.action_add).number = 2

R.id.action_add serait pour vous l'identifiant de l'élément de menu sur lequel vous souhaitez placer un badge. Vérifiez-le à partir du fichier de menu que vous avez fourni au BottomNavigationView.

Assurez-vous que le thème de votre application est dans Theme.MaterialComponents.

vous pouvez le vérifier dans les styles ou manifeste. pour cet exemple le mien était-ce

     <style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="Android:statusBarColor" tools:targetApi="Lollipop">@color/colorPrimary</item>
    </style>
26
Abel

Je faisais face au même problème et je ne voulais pas utiliser une bibliothèque.

J'ai donc créé une présentation personnalisée appelée layout_news_badge:

<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/badge_frame_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <TextView
        Android:id="@+id/badge_text_view"
        Android:layout_width="19dp"
        Android:layout_height="19dp"
        Android:textSize="11sp"
        Android:textColor="@Android:color/white"
        Android:background="@drawable/news_bottom_nav_bg"
        Android:layout_gravity="top"
        Android:layout_marginTop="4dp"
        Android:layout_marginStart="16dp"
        Android:gravity="center"
        Android:padding="2dp"
        tools:text="9+" />
</FrameLayout>

Arrière-plan TextView (news_bottom_nav_bg):

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="oval">
    <solid Android:color="?attr/colorPrimary" />
</shape>

Ensuite, j'ai créé un BottomMenuHelper avec ces 2 méthodes:

public static void showBadge(Context context, BottomNavigationView 
    bottomNavigationView, @IdRes int itemId, String value) {
    removeBadge(bottomNavigationView, itemId);
    BottomNavigationItemView itemView = bottomNavigationView.findViewById(itemId);
    View badge = LayoutInflater.from(context).inflate(R.layout.layout_news_badge, bottomNavigationView, false);

    TextView text = badge.findViewById(R.id.badge_text_view);
    text.setText(value);
    itemView.addView(badge);
}

public static void removeBadge(BottomNavigationView bottomNavigationView, @IdRes int itemId) {
    BottomNavigationItemView itemView = bottomNavigationView.findViewById(itemId);
    if (itemView.getChildCount() == 3) {
        itemView.removeViewAt(2);
    }
}

Puis quand je l'appelle dans mon activité:

BottomMenuHelper.showBadge(this, mBottomNavigationView, R.id.action_news, "1");

EDIT: Amélioration ajoutée par suggestion jatin rana

24
ilbose

sur la base de la réponse de @ Tinashe, j'aimerais que le badge apparaisse comme ci-dessous sans numéro: enter image description here

code:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
        // position = 2
        addBadge(POSITION_HISTORY)
    }

    /**
     * add badge(notification dot) to bottom bar
     * @param position to get badge container
     */
    @SuppressLint("PrivateResource")
    private fun addBadge(position: Int) {
        // get badge container (parent)
        val bottomMenu = navigation.getChildAt(0) as? BottomNavigationMenuView
        val v = bottomMenu?.getChildAt(position) as? BottomNavigationItemView

        // inflate badge from layout
        badge = LayoutInflater.from(this)
                .inflate(R.layout.badge_layout, bottomMenu, false)

        // create badge layout parameter
        val badgeLayout: FrameLayout.LayoutParams = FrameLayout.LayoutParams(badge?.layoutParams).apply {
            gravity = Gravity.CENTER_HORIZONTAL
            topMargin = resources.getDimension(R.dimen.design_bottom_navigation_margin).toInt()

            // <dimen name="bagde_left_margin">8dp</dimen>
            leftMargin = resources.getDimension(R.dimen.bagde_left_margin).toInt()
        }

        // add view to bottom bar with layout parameter
        v?.addView(badge, badgeLayout)
    }

badge_layout.xml (badge_size = 12dp)

<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="@dimen/badge_size"       
    Android:layout_height="@dimen/badge_size"
    Android:background="@drawable/new_notification" />

et fond dessinable new_notification.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape="oval">
    <corners Android:radius="100dp"/>
    <solid Android:color="#F44336"/>
</shape>
9
vuhung3990

Comme @zxbin, répondez. vous pouvez vérifier BadgeView et essayer le code ci-dessous

BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(this);
navigation.setSelectedItemId(R.id.navigation_store);
BottomNavigationMenuView bottomNavigationMenuView =
        (BottomNavigationMenuView) navigation.getChildAt(0);
View v = bottomNavigationMenuView.getChildAt(4); // number of menu from left
new QBadgeView(this).bindTarget(v).setBadgeNumber(5);

source de my Gist

6
Agi Maulana

Badge a maintenant été ajouté à AndroidX BottomNavigationView par BadgeDrawable. Voir la documentation

fun setBadge(count: Int) {
    if (count == 0) {
        bottomNavigationView.removeBadge(R.id.ticketsNavigation)
    } else {
        val badge = bottomNavigationView.showBadge(R.id.ticketsNavigation)
        badge.number = count
        badge.backgroundColor = getColor(R.color.badge)
        badge.badgeTextColor = getColor(R.color.blackTextColor)
    }
}

// Menu:
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item
        Android:id="@+id/ticketsNavigation"
        Android:icon="@drawable/vector_drawable_navbar_tickets"
        Android:title="@string/tickets_title"/>
    ...
</menu>
1
Morten Holmgaard

Vous pouvez essayer de cette façon:

Mettez un TextView à l'intérieur du BottomNavigationView pour compter ( BottomNavigationView est un FrameLayout ):

    <Android.support.design.widget.BottomNavigationView Android:id="@id/bottomMenu" style="@style/bottomMenu">
        <TextView Android:id="@id/bottomMenuSelectionsNumber" style="@style/bottomMenuSelectionsNumber"/>
    </Android.support.design.widget.BottomNavigationView>

Et leur style comme ça:

<style name="bottomMenu">
    <item name="Android:layout_width">match_parent</item>
    <item name="Android:layout_height">@dimen/toolbarHeight</item>
    <item name="Android:layout_gravity">center|bottom</item>
    <item name="Android:background">@color/colorThird</item>
    <item name="itemBackground">@drawable/tabs_ripple</item>
    <item name="itemIconTint">@drawable/bottom_menu_item_color</item>
    <item name="itemTextColor">@drawable/bottom_menu_item_color</item>
    <item name="menu">@menu/bottom_menu</item>
</style>

<style name="bottomMenuSelectionsNumber">
    <item name="Android:text">@string/bottomMenuSelectionsNumber</item>
    <item name="Android:textSize">@dimen/appSecondFontSize</item>
    <item name="Android:textColor">@color/white</item>
    <item name="Android:layout_width">@dimen/bottomMenuSelectionsNumberDim</item>
    <item name="Android:layout_height">@dimen/bottomMenuSelectionsNumberDim</item>
    <item name="Android:layout_gravity">right|bottom</item>
    <item name="Android:layout_marginRight">@dimen/bottomMenuSelectionsNumberMarginR</item>
    <item name="Android:layout_marginBottom">@dimen/bottomMenuSelectionsNumberMarginB</item>
    <item name="Android:gravity">center</item>
    <item name="Android:includeFontPadding">false</item>
    <item name="Android:background">@drawable/bottom_menu_selections_number_bg</item>
</style>

Et bottom_menu_selections_number_bg :

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="oval">
    <solid Android:color="@color/colorAccent"/>
    <corners Android:radius="@dimen/cornerRadius"/>
</shape>
1
Arash

S'il vous plaît essayez cela une fois.

1) Créer un fichier XML pour le badge (par exemple, notification_badge_view.xml)

<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <ImageView
        Android:id="@+id/badge"
        Android:layout_width="20dp"
        Android:layout_height="20dp"
        Android:layout_gravity="top|center_horizontal"
        Android:layout_marginStart="10dp"
        Android:gravity="center"
        Android:padding="3dp"
        app:srcCompat="@drawable/notification_badge" />
</FrameLayout>

2) Créer un fichier pouvant être dessiné pour la forme du point de notification (ex. Badge_circle.xml)

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape="oval">
    <solid Android:color="@color/colorAccent" />
    <stroke
        Android:width="2dp"
        Android:color="@Android:color/white" />
</shape>

3) Dans votre méthode d’activité onCreate, ajoutez la vue de badge à BottomNavigationView

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_landing);

         addBadgeView();

    }

4) Et la méthode addBadgeView est ci-dessous

private void addBadgeView() {
        try {
            BottomNavigationMenuView menuView = (BottomNavigationMenuView) bottomNavigationBar.getChildAt(0);
            BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(0); //set this to 0, 1, 2, or 3.. accordingly which menu item of the bottom bar you want to show badge
            notificationBadge = LayoutInflater.from(LandingActivity.this).inflate(R.layout.view_notification_badge, menuView, false);
            itemView.addView(notificationBadge);
            notificationBadge.setVisibility(GONE);// initially badge will be invisible 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Remarque: bottomNavigationBar est votre vue de barre inférieure.

5) Actualiser le badge à afficher et à masquer selon la méthode suivante

private void refreshBadgeView() {
        try {
            boolean badgeIsVisible = notificationBadge.getVisibility() != GONE;
            notificationBadge.setVisibility(badgeIsVisible ? GONE : VISIBLE);//makes badge visible and invisible 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

6) Et finissez par masquer lorsque vous cliquez sur une page de la barre inférieure en suivant la ligne.

bottomNavigationBar.setOnNavigationItemSelectedListener(new 
BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) 
              {
                switch (menuItem.getItemId()) {
                    case R.id.bottom_bar_one:
                        //while moving to first fragment
                        notificationBadge.setVisibility(GONE);
                        break;
                    case R.id.bottom_bar_two:
                        //moving to second fragment
                        break;
                    case R.id.bottom_bar_three:
                        //moving to third fragment
                        break;
                }
                return true;
            }
        });
0
Surendar D

La réponse de @ Abel est la meilleure, sauf si vous avez déjà un ensemble complexe de thèmes et n'avez pas le temps de les changer tous.

Toutefois, si a) vous êtes pressé par le temps et si vous utilisez la barre BottomNavigationView de la bibliothèque de matériaux Google ou b) si vous souhaitez ajouter votre propre badge d'affichage personnalisé, la réponse acceptée ne fonctionnera pas avec com.google.Android.material:material:1.1.0

Vous devrez coder pour une hiérarchie de vues différente de celle de la réponse acceptée

  BottomNavigationItemView itemView = (BottomNavigationItemView) ((BottomNavigationMenuView) mBottomNavigation.getChildAt(0)).getChildAt(2);
  View badge = LayoutInflater.from(this).inflate(R.layout.navigation_dot, itemView, false);
  itemView.addView(badge);

si vous souhaitez mettre à jour votre thème et mettre à jour vers

com.google.Android.material:material:1.1.0-alpha09

alors tout ce que vous devez faire à la place est

mBottomNavigation.getOrCreateBadge(R.id.navigation_menu_item_one).setNumber(YOUR_NUMBER);

Les fonctions de suppression et de numérotation ne sont présentes que dans la version 1.1.0-alpha09 (et supérieure)

0
d4c0d312

L'utilisation de la bibliothèque de support BottomNavigationView est difficile. Une solution simple consiste à utiliser des composants externes. Un facile à manipuler est: https://github.com/roughike/BottomBar Consulter sa documentation, c'est aussi simple que:

BottomBarTab nearby = bottomBar.getTabWithId(R.id.tab_nearby);
nearby.setBadgeCount(5);

// Remove the badge when you're done with it.
nearby.removeBadge/();
0
Fran

vous pouvez utiliser cette bibliothèque .. pour ajouter un badge sur la barre de navigation

https://github.com/ahmedewess/Badged-BottomNavigationBar

enter image description here

0
ahmed ewess