web-dev-qa-db-fra.com

Changement de couleur de fond dans BottomNavigationView

J'ai implémenté BottomNavigationView qui est disponible à partir de la nouvelle bibliothèque de support 25.0.0. Voici mon code pour ça

<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/text"
    app:itemTextColor="@drawable/text"
    app:menu="@menu/bottom_navigation_main" />

Et text.xml tirable

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:color="@Android:color/white" Android:state_enabled="true" />
    <item Android:color="@color/colorPrimaryDark" Android:state_enabled="false" />
</selector>

Avec ce code, je peux changer la couleur du texte quand un élément de menu est cliqué, mais quand j'applique la même chose à app:itemBackground il montre une erreur <item> tag requires a 'drawable' attribute or child tag defining a drawable.

C'est ce que j'ai essayé pour app:itemBackground

app:itemBackground="@drawable/text"

Ma question est donc comment puis-je changer la couleur de fond de l'élément de menu sélectionné?

25
Ravi Rupareliya

trouvé une réponse à partir de ceci post moyen

  1. Nous devons utiliser Android:state_checked au lieu de Android:state_enabled
  2. dans onNavigationItemSelected vous devez utiliser return true au lieu de return false.

et pour définir l’arrière-plan, nous ne pouvons pas utiliser Android:color dans <item>, nous devons utiliser Android:drawable

Alors voici à quoi ça ressemble un fichier XML lorsque vous le configurez pour app:itemTextColor et app:itemIconTint

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:color="@color/colorPrimaryDark" Android:state_checked="true" />
    <item Android:color="@Android:color/white" Android:state_checked="false" />
</selector>

et pour mettre app:itemBackground sélecteur

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:drawable="@drawable/banner_white" Android:state_checked="true"/>
    <item Android:drawable="@drawable/banner_green" Android:state_checked="false"/>
</selector>

Ici banner_white et banner_green sont des pngs.

35
Ravi Rupareliya

J'ai rencontré un problème similaire à celui des PO, mais un peu différent. Si vous mettez sth comme @color/color_selector Dans le BottomNavigationView app:itemBackground="___". La vue sera masquée dans le panneau de conception et l'application sera écrasée lors du lancement. Bien que cela fonctionne bien si vous venez de le définir sur une couleur constante comme @color/black.

Pour une explication plus détaillée, j’ai creusé dans la référence Android api. Maintenant, je pense avoir trouvé la réponse qui peut raisonnablement résoudre ce problème. (Peut ne pas être précis.)

Le problème est, ce que vous fournissez n'est PAS EXACTEMENT ce qu'ils ont demandé .

app:itemIconTint Et app:itemTextColor Demandent une couleur hexadécimale, tandis que app:itemBackground Demande littéralement Drawable . Les éléments <color> Que nous écrivons dans colors.xml Sont ColorDrawable . Il est dérivé de Drawable afin qu'il puisse nourrir les trois attributs.

Cependant, lorsque vous le changez pour utiliser un sélecteur, les choses deviennent différentes. Les couleurs hexagonale et imprimable ont un sélecteur correspondant. Un sélecteur agit comme la ressource que vous avez insérée, mais le résultat n'est pas celui d'origine. Cela ressemble plus à un emballage à usage unique. Vous ne pouvez pas attribuer une couleur hexadécimale à un attribut nécessitant un Drawable.

Le sélecteur de couleur est en fait un ColorStateList , ==, fournit une couleur hexadécimale, réside dans res/color. Vous ne pouvez utiliser que l'attribut Android:color Dans ce fichier. cela provoquera une erreur si vous écrivez Android:drawable.
Le sélecteur pouvant être dessiné est StateListDrawable , fournit Drawable, réside dans res/drawable. Vous devriez écrire Android:drawable Ici, mais il n'y a pas d'erreur si vous écrivez Android:color.

Cependant, Android:color Fournit uniquement une couleur hexadécimale qui ne peut pas être reconnue en tant que Drawable, alors que app:itemBackground Nécessite a Drawable , donc l'application est condamnée. (cause directe)

Les deux attributs (Android:color Et Android:drawable) Acceptent un ColorDrawable, cela fonctionne comme si vous définissiez une couleur constante.

La solution (et la pratique) est la suivante:

  • Utilisez (et seulement) Android:drawable Dans un res/drawable/drawable_selector.xml. Exemple:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <item Android:drawable="@color/colorAccent" Android:state_checked="true" />
        <item Android:drawable="@color/colorAccentDark" />
    </selector>
    
  • Utilisez res/color/color_selector.xml Lorsque cela nécessite une couleur hexadécimale (pour éviter toute confusion). Exemple:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <item Android:color="@Android:color/white" Android:state_checked="true"/>
        <item Android:color="@color/colorPrimary" />
    </selector>
    
  • Fournissez app:itemBackground Avec drawable. Exemple:

    <Android.support.design.widget.BottomNavigationView
        ...
        app:itemBackground="@drawable/drawable_selector"
        app:itemIconTint="@color/color_selector"
        app:itemTextColor="@color/color_selector"
        ... />
    

(A noter que si vous utilisez Android Studio, sa fonction de saisie semi-automatique vous indiquera quels attributs sont légaux et disponibles, et cela ne vous suggère pas Android:color sélecteur sous res/drawable!)

14
UnluckyNinja

Essayez ceci, c’est un exemple de code d’écouteur de sélection d’éléments de navigation. espérons que cela vous aide.

 @Override
  public boolean onNavigationItemSelected(final MenuItem menuItem) {
    // update highlighted item in the navigation menu
    menuItem.setChecked(true);
    mNavItemId = menuItem.getItemId();

    // allow some time after closing the drawer before performing real navigation
    // so the user can see what is happening
    mDrawerLayout.closeDrawer(GravityCompat.START);
    mDrawerActionHandler.postDelayed(new Runnable() {
      @Override
      public void run() {
        navigate(menuItem.getItemId());
      }
    }, DRAWER_CLOSE_DELAY_MS);
    return true;
  }

Solution alternative:

Créez un fichier drawable highlight_color.xml avec le contenu suivant:

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="rectangle">
     <solid Android:color="YOUR HIGHLIGHT COLOR"/>
</shape>

Créez un autre fichier dessinable nav_item_drawable.xml avec le contenu suivant:

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <item Android:drawable="@drawable/highlight_color" Android:state_checked="true"/>
</selector>

Enfin, ajoutez la balise app: itemBackground dans le NavView:

<Android.support.design.widget.NavigationView
Android:id="@+id/activity_main_navigationview"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_gravity="start"
app:headerLayout="@layout/drawer_header"
app:itemIconTint="@color/black"
app:itemTextColor="@color/primary_text"
app:itemBackground="@drawable/nav_item_drawable"
app:menu="@menu/menu_drawer">

ici, le fichier highlight_color.xml définit une couleur unie pouvant être dessinée pour l’arrière-plan. Plus tard, cette couleur est désignée par le sélecteur nav_item_drawable.xml.

Essaye celui-là.

2
Apoorv Mehrotra

commencez par créer xml bottom_navigation_items avec

`<ripple xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:color="?android:colorControlHighlight">
    <item>
        <selector>
            <item
                Android:drawable="@color/primary_bottom_select"
                Android:state_checked="true" />
            <item
                Android:drawable="@color/bottom_navigation"
                Android:state_checked="false" />
        </selector>
    </item>
</ripple>`

deuxième: ajouter app:itemBackground="@drawable/bottom_navigation_items"

1
Yakov Weber