2015-06-17 13 views
59

Sto utilizzando la nuova libreria di Android Design Support per implementare un cassetto di navigazione nella mia applicazione.Cambiare il colore di una voce di menu selezionata in un cassetto di navigazione

Non riesco a capire come modificare il colore di un elemento selezionato!

Ecco il codice XML del menu:

<menu xmlns:android="http://schemas.android.com/apk/res/android"> 
<group android:checkableBehavior="single"> 
    <item 
     android:id="@+id/navigation_item_1" 
     android:icon="@drawable/ic_1" 
     android:title="@string/navigation_item_1"/> 

    <item 
     android:id="@+id/navigation_item_2" 
     android:icon="@drawable/ic_2" 
     android:title="@string/navigation_item_2"/> 
</group> 

E qui è il xml navigationview che si trova all'interno di un android.support.v4.widget.DrawerLayout:

<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:menu="@menu/menu_drawer"> 

    <TextView 
     android:id="@+id/main_activity_version" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="bottom" 
     android:layout_marginBottom="@dimen/activity_vertical_margin" 
     android:layout_marginLeft="@dimen/activity_horizontal_margin" 
     android:textColor="@color/primary_text" /> 

</android.support.design.widget.NavigationView> 

Grazie per il vostro aiuto!

[EDIT] Ho già visto soluzioni come questa: Change background color of android menu.

Sembra essere piuttosto un hack e ho pensato che con la nuova libreria di supporto del design, sarebbe stato introdotto qualcosa di più pulito?

+0

possibile duplicato di [Cambia colore di sfondo del menu di Android] (http://stackoverflow.com/questions/2719173/change-background-color-of-android-menu) – jlopez

risposta

177

Ebbene si può raggiungere questo obiettivo usando Color State Resource. Se si nota all'interno del vostro NavigationView si sta utilizzando

app:itemIconTint="@color/black" 
app:itemTextColor="@color/primary_text" 

Qui invece di utilizzare @color/black o @color/primary_test, utilizzare un Color State List Resource. Per questo, prima crea un nuovo xml (ad esempio drawer_item.xml) all'interno della directory color (che dovrebbe essere all'interno della directory res). Se non si dispone già di una directory denominata color, crearne una.

Ora all'interno drawer_item.xml fare qualcosa di simile

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:color="checked state color" android:state_checked="true" /> 
    <item android:color="your default color" /> 
</selector> 

fase finale sarebbe quello di cambiare la vostra NavigationView

<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/drawer_item" // notice here 
    app:itemTextColor="@color/drawer_item" // and here 
    app:itemBackground="@android:color/transparent"// and here for setting the background color to tranparent 
    app:menu="@menu/menu_drawer"> 

come non è possibile utilizzare diversi colori Lista Stato Risorse per IconTint, ItemTextColor, ItemBackground.

Ora quando si imposta un elemento come selezionato (in xml o in modo programmatico), l'elemento in questione avrà un colore diverso da quelli non selezionati.

+0

Ricorda che per funzionare è necessario modificarlo da Android: state_checked per android: state_pressed. – Programista

+28

per ItemBackground è necessario utilizzare un drawable anziché il colore perché non è possibile definire uno sfondo utilizzando una risorsa colore. – sirFunkenstine

+0

@sash se vogliamo modificare l'immagine dell'icona sulla voce di navigazione selezionata, allora come faremo? – mohit

2

una necessità di impostare NavigateItem controllare vero ogni volta elemento in NavigateView viene cliccato

//listen for navigation events 
NavigationView navigationView = (NavigationView)findViewById(R.id.navigation); 
navigationView.setNavigationItemSelectedListener(this); 
// select the correct nav menu item 
navigationView.getMenu().findItem(mNavItemId).setChecked(true); 

Aggiungere NavigationItemSelectedListener su NavigationView

@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; 
    } 
+0

Grazie per il vostro aiuto Vikalp, ma io sono già facendo ciò ('setChecked (true)'). Posso vedere cambiare il colore della voce selezionata, ma non posso modificarlo da solo, il colore è sempre una versione più leggera dello sfondo di navigatioview. – Greg

+0

@Greg Per impostazione predefinita, 'setChecked (true)' su 'View' cambia colore di sfondo fino al tema del dispositivo che si utilizza. Se si modifica lo sfondo dell'elemento con un altro colore, è necessario gonfiare il layout in 'DrawerLayout' o' NavigationView' e gestirlo autonomamente. –

+0

grazie ancora, ho provato a fare quello che mi hai detto ma senza successo, avresti un link che spiega come, per favore? – Greg

1

Ecco l'altro modo per raggiungere questo obiettivo:

public boolean onOptionsItemSelected(MenuItem item) { 

    int id = item.getItemId(); 

    item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { 
     @Override 
     public boolean onMenuItemClick(MenuItem item) { 
      item.setEnabled(true); 
      item.setTitle(Html.fromHtml("<font color='#ff3824'>Settings</font>")); 
      return false; 
      } 
     }); 


    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 

}

40

credo app:itemBackground aspetta un disegnabile. Quindi, seguire la seguente procedura:

creare un file drawable highlight_color.xml con i seguenti contenuti:

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

fare un altro file di drawable nav_item_drawable.xml con i seguenti contenuti:

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

Infine aggiungere app:itemBackground tag nel 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"> 

qui il file highlight_color.xml definisce un colore solido che può essere disegnato per lo sfondo. Successivamente questo drawable di colori è assegnato al selettore nav_item_drawable.xml.

Questo ha funzionato per me. Speriamo che questo possa aiutare.

********************************************** AGGIORNATO **********************************************

Anche se la risposta di cui sopra ti dà un controllo preciso alcune proprietà, ma il modo in cui io sto per descrivere si sente più SOLID ed è un po 'COOLER.

Che cosa si può fare è, è possibile definire un ThemeOverlay nel styles.xml per il NavigationView come questo:

<style name="ThemeOverlay.AppCompat.navTheme"> 

     <!-- Color of text and icon when SELECTED --> 
     <item name="colorPrimary">@color/color_of_your_choice</item> 

     <!-- Background color when SELECTED --> 
     <item name="colorControlHighlight">@color/color_of_your_choice</item> 

    </style> 

ora diffusa questa ThemeOverlay a app:theme attributo della NavigationView, in questo modo:

<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:theme="@style/ThemeOverlay.AppCompat.navTheme" 
app:headerLayout="@layout/drawer_header" 
app:menu="@menu/menu_drawer"> 

Spero che questo possa essere d'aiuto.

+1

Inoltre, questo metodo può essere usato come 'android: background =" @ drawable/nav_item_drawable "' per altri widget come RadioButton, Checkbox, Button ecc. Riduce la programmazione bloatware per la gestione di 'setOnCheckedChangeListener' solo per l'evidenziazione dei colori. – rupinderjeet

+0

@Ankush funziona ma il testo e l'icona scompaiono, ho impostato anche il colore della tinta dell'articolo ma non funziona. puoi per favore suggerirmi come può essere fatto – User

+0

@User Non so cosa sia andato storto con il tuo codice, ma ho aggiunto la risposta. Un modo completamente diverso per ottenere la stessa cosa con meno sforzo. Puoi verificarlo. – Ankush

Problemi correlati