Cassetto di navigazione: come impostare l'elemento selezionato all'avvio?


229

Il mio codice funziona perfettamente: ogni volta che si fa clic su un elemento nel Cassetto di navigazione, l'elemento viene selezionato.

Ovviamente voglio avviare l'app con un frammento predefinito (home), ma il Navigatore non ha l'elemento selezionato. Come posso selezionare quell'elemento a livello di codice?

public class BaseApp extends AppCompatActivity {

    //Defining Variables
    protected String LOGTAG = "LOGDEBUG";
    protected Toolbar toolbar;
    protected NavigationView navigationView;
    protected DrawerLayout drawerLayout;

    private DateManager db = null;

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

        navigationView = (NavigationView) findViewById(R.id.navigation_view);


        // set the home/dashboard at startup

        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.frame, new DashboardFragment());
        fragmentTransaction.commit();

        setNavDrawer();
    }

    private void setNavDrawer(){

        // Initializing Toolbar and setting it as the actionbar
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //Initializing NavigationView

        //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            // This method will trigger on item Click of navigation menu
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {


                //Checking if the item is in checked state or not, if not make it in checked state

                // I THINK THAT I NEED EDIT HERE...

                if (menuItem.isChecked()) menuItem.setChecked(false);
                else menuItem.setChecked(true);

                //Closing drawer on item click
                drawerLayout.closeDrawers();


                //Check to see which item was being clicked and perform appropriate action
                switch (menuItem.getItemId()) {    

                    //Replacing the main content with ContentFragment 

                    case R.id.home:

                        DashboardFragment dashboardFragment = new DashboardFragment();
                        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.replace(R.id.frame, dashboardFragment,"DASHBOARD_FRAGMENT");
                        fragmentTransaction.commit();
                        return true;
[...]

Penso che devo modificare qui:

if (menuItem.isChecked()) menuItem.setChecked(false);
                    else menuItem.setChecked(true);

O onCreateall'avvio dell'app con FragmentTransaction.

Grazie per il vostro sostegno.


Una delle risposte attiva onNavigationItemSelectedun'azione per l'id selezionato?
Prabs,

Risposte:


478

Usa il codice qui sotto:

navigationView.getMenu().getItem(0).setChecked(true);

Chiama questo metodo dopo aver chiamato setNavDrawer();

Il getItem(int index)metodo ottiene MenuItemquindi puoi chiamarlo setChecked(true);on MenuItem, tutto ciò che ti resta da fare è scoprire quale indice di elemento ha il valore predefinito e sostituire lo 0 con quell'indice.

È possibile selezionare (evidenziare) l'elemento chiamando

onNavigationItemSelected(navigationView.getMenu().getItem(0));

Ecco un link di riferimento: http://thegeekyland.blogspot.com/2015/11/navigation-drawer-how-set-selected-item.html

EDIT non ha funzionato su Nexus 4, supporta la revisione della libreria 24.0.0. Raccomando l'uso

navigationView.setCheckedItem(R.id.nav_item);

rispose @kingston di seguito.


65
Aggiunte librerie di supporto Android v23 setCheckedItem (int id).
Markus Rubey,

1
@MarkusRubey anche dopo aver impostato setCheckedItem Non sono in grado di evidenziare l'elemento selezionato. Potresti dire la possibile ragione?
Dexto,

3
Non ha funzionato per me! Quando viene chiamato il metodo onNavigationItemSelected per altre opzioni nel menu del menu di navigazione, l'elemento iniziale denominato "controllato" mantiene sempre il suo stato. Quando utilizzo "navigationView.setCheckedItem (id);" ha funzionato perfettamente! Successivamente, deve chiamare il metodo 'navigationView.getMenu () performIdentifierAction (R.id.nav_market, 0);' per eseguire la selezione dell'elemento desiderato.
GFPF,

3
Nessuno dei due metodi citati ha funzionato per me per qualche motivo. Ma fare navigationView.post(new Runnable() { navigationView.setCheckedItem(...) })- ha funzionato.
Dimsuz,

1
Probabilmente stai provando a cambiare l'elemento selezionato da un thread diverso rispetto al thread principale :)
Arlind,

105

Puoi anche chiamare:

navigationView.setCheckedItem(id);

Questo metodo è stato introdotto nell'API 23.0.0

Esempio

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      tools:ignore="UnusedIds">

    <group
        android:id="@+id/group"
        android:checkableBehavior="single">
        <item
            android:id="@+id/menu_nav_home"
            android:icon="@drawable/ic_home_black_24dp"
            android:title="@string/menu_nav_home" />
    </group>
</menu>

Nota: android:checkableBehavior="single"

Vedi anche questo


1
anche dopo aver impostato setCheckedItem Non sono in grado di evidenziare l'elemento selezionato. Potresti dire la possibile ragione?
Dexto,

3
@DeepeshDoshi Assicurati di avere un comportamento verificabile.
Jared Burrows,

1
dovrebbe lui navigationView.setCheckedItem (R.id.menu_nav_home) per selezionare il menu principale
jaga

per singolo articolo basta aggiungere android:checkable="true"altro non verrà controllato da solo.
sud007,

Assicurati anche di non chiamare questo metodo da con navItemSelecteListenerpoiché l'elemento è selezionato dopo che questo metodo ritorna.
Mallaudin,

47

Per me entrambi questi metodi non hanno funzionato:

  • navigationView.getMenu().getItem(0).setChecked(true);
  • navigationView.setCheckedItem(id);

Prova questo, funziona per me.

onNavigationItemSelected(navigationView.getMenu().findItem(R.id.nav_profile));


2
Grazie per questo suggerimento. I metodi di cui sopra sono effettivamente ok, ma il problema è diverso: se li usi, onNavigationItemSelected non verrà chiamato, verrà controllata solo la voce di menu. Quindi dobbiamo chiamare entrambi i metodi.
user1209216

2
onNavigationItemSelected (navView.getMenu () getItem (0).); o onNavigationItemSelected (navView.getMenu (). getItem (R.id.nav_profile)); entrambi hanno funzionato per me, getitem invece di finditem.
Harsh Dalwadi,

30

Esempio ( NavigationView.OnNavigationItemSelectedListener ):

private void setFirstItemNavigationView() {
        navigationView.setCheckedItem(R.id.custom_id);
        navigationView.getMenu().performIdentifierAction(R.id.custom_id, 0);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setFirstItemNavigationView();
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    FragmentManager fragmentManager = getFragmentManager();

    switch (item.getItemId()) {
        case R.id.custom_id:
            Fragment frag = new CustomFragment();

            // update the main content by replacing fragments
            fragmentManager.beginTransaction()
                    .replace(R.id.viewholder_container, frag)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .addToBackStack(null)
                    .commit();
            break;
    }

Tks


2
Questo è un modo per farlo, mi piace. Tuttavia, le risposte solo al codice sono spesso scoraggiate. Modificherei la tua risposta per spiegare un po 'il codice, ad esempio perché usi performIdentifierActione cosa sta succedendo onNavigationItemSelected. A te può sembrare semplice, ma un nuovo sviluppatore potrebbe avere difficoltà a comprendere il tuo codice.
AdamMc331,

@ McAdam331 Certo, sentiti libero, è passato metà qui oggi e non ho avuto il tempo di scrivere in modo più dettagliato.
GFPF,

25

Ci sono sempre problemi con le librerie di supporto "oh so great" di Google. Se si desidera controllare un elemento senza eseguire il downgrade della versione delle librerie di supporto, è sufficiente impostare controllabile prima di impostare lo stato controllato.

MenuItem item = drawer.getMenu().findItem(R.id.action_something);
item.setCheckable(true);
item.setChecked(true);

Potrebbe funzionare anche se si imposta controllabile nel menu file xml



9

L'API 23 fornisce il seguente metodo:

navigationView.setCheckedItem(R.id.nav_item_id);

Tuttavia, per qualche motivo questa funzione non ha causato l'esecuzione del codice dietro l'elemento di navigazione. Il metodo evidenzia certamente l'elemento nel riquadro di navigazione o lo "controlla", ma non sembra chiamare il OnNavigationItemSelectedListenerrisultato in una schermata vuota all'avvio se la schermata di avvio dipende dalle selezioni del riquadro di navigazione. È possibile chiamare manualmente l'ascoltatore, ma sembra confuso:

if (savedInstanceState == null) this.onNavigationItemSelected(navigationView.getMenu().getItem(0));

Il codice sopra presuppone:

  1. Hai implementato NavigationView.OnNavigationItemSelectedListenernella tua attività
  2. Hai già chiamato:
    navigationView.setNavigationItemSelectedListener(this);
  3. L'articolo che si desidera selezionare si trova in posizione 0

6

Devi chiamare 2 funzioni per questo:

Primo: per eseguire i comandi che hai implementato nel onNavigationItemSelectedlistener:

onNavigationItemSelected(navigationView.getMenu().getItem(R.id.nav_camera));

Secondo: per modificare lo stato della voce di menu del riquadro di navigazione su selezionato (o selezionato):

navigationView.setCheckedItem(R.id.nav_camera);

Ho chiamato entrambe le funzioni e ha funzionato per me.


5

Il seguente codice renderà selezionata solo la voce di menu:

navigationView.setCheckedItem(id);

Per selezionare e aprire la voce di menu, aggiungere il seguente codice dopo la riga sopra.

onNavigationItemSelected(navigationView.getMenu().getItem(0));


4

Questa è la mia soluzione, molto semplice.

Ecco il mio file menu.xml:

<group
    android:id="@+id/grp1"
    android:checkableBehavior="single">
    <item
        android:id="@+id/nav_all_deals"
        android:checked="true"
        android:icon="@drawable/ic_all_deals"
        android:title="@string/all_deals" />
    <item
        android:id="@+id/nav_news_and_events"
        android:icon="@drawable/ic_news"
        android:title="@string/news_and_events" />
    <item
        android:id="@+id/nav_histories"
        android:icon="@drawable/ic_histories"
        android:title="@string/histories" />
</group>

Il menu in alto evidenzierà la prima voce di menu. La riga sotto farà qualcosa (es: mostra il primo frammento, ecc.). NOTA: scrivere dopo 'configura il codice del cassetto'

onNavigationItemSelected(mNavigationView.getMenu().getItem(0));

4

Il modo più semplice è selezionarlo da XML come segue,

<menu>
   <group android:checkableBehavior="single">
         <item
              android:checked="true"
              android:id="@+id/nav_home"
              android:icon="@drawable/nav_home"
              android:title="@string/main_screen_title_home" />

Nota la linea android:checked="true"


1
A mio avviso, la migliore risposta, causa utilizza la logica fornita da Android predefinita. Votato solo come migliore è meglio, se il menu utilizza il layout e viene generato dall'adattatore non dal file xml del menu.
Andris,

1
Questa è la risposta migliore
Ganesh Chowdhary Sadanala,

2

Innanzitutto crea i colori per l'elemento selezionato. Qui https://stackoverflow.com/a/30594875/1462969 buon esempio. Ti aiuta a cambiare il colore dell'icona. Per cambiare lo sfondo di tutti gli elementi selezionati, aggiungi questo file. \ Style.xml

  <item name="selectableItemBackground">@drawable/selectable_item_background</item>

Dove selectable_item_background deve essere dichiarato in drawable / selectable_item_background.xml

  <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/accent_translucent"
      android:state_pressed="true" />
    <item android:drawable="@android:color/transparent" />
   </selector>

Dove il colore può essere dichiarato in style.xml

 <color name="accent_translucent">#80FFEB3B</color>

E dopo questo

   // The main navigation menu with user-specific actions
        mainNavigationMenu_ = (NavigationView) findViewById(R.id.main_drawer);
        mainNavigationMenu_.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                mainNavigationMenu_.getMenu().findItem(itemId).setChecked(true);
                return true;
            }
        });

Come vedi ho usato questo mainNavigationMenu_.getMenu (). FindItem (itemId) .setChecked (true); per impostare l'elemento selezionato. Qui navigationView

 <android.support.design.widget.NavigationView
        android:id="@+id/main_drawer"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/header_main_navigation_menu"
        app:itemIconTint="@color/state_list"
        app:itemTextColor="@color/primary"
        app:menu="@menu/main_menu_drawer"/>

Mi piace questo metodo, attualmente lo uso nel mio progetto. Potrebbe essere utile includere il @color/state_listcodice nella risposta. Per curiosità, dove hai preso la convenzione di denominazione per mettere un carattere di sottolineatura alla fine del nome della variabile? Non ho mai visto questo approccio.
AdamMc331,

Penso che forse vuoi menuItem.getItemId()inveceitemId
Craig Russell il

2

Quando si utilizzano BottomNavigationViewle altre risposte come navigationView.getMenu().getItem(0).setChecked(true);e navigationView.setCheckedItem(id);non funziona, la chiamata setSelectedItemIdfunziona:

    BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation_view);

    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
            // TODO: 10-Aug-19 your code here 
        }
    });

    bottomNavigationView.setSelectedItemId(R.id.myitem);

0

Crea un selettore per l'elemento Individuale del cassetto di navigazione

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

Apporta alcune modifiche in NavigationView

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:itemBackground="@drawable/drawer_item"
        android:background="@color/textBlue"
        app:itemIconTint="@color/white"
        app:itemTextColor="@color/white"
        app:menu="@menu/activity_main_drawer"
        />

0

sulla tua attività (dietro il cassetto):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar,
               R.string.navigation_drawer_open,
               R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    navigationView.setCheckedItem(R.id.nav_portfolio);
    onNavigationItemSelected(navigationView.getMenu().getItem(0));
}

e

@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    Fragment fragment = null;

    if (id == R.id.nav_test1) {
        fragment = new Test1Fragment();
        displaySelectedFragment(fragment);
    } else if (id == R.id.nav_test2) {
        fragment = new Test2Fragment();
        displaySelectedFragment(fragment);
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

e nel tuo menu:

<group android:checkableBehavior="single">

    <item
        android:id="@+id/nav_test1"
        android:title="@string/test1" />

    <item
        android:id="@+id/nav_test2"
        android:title="@string/test2" />

  </group>

quindi il primo menu è evidenziato e mostra come menu predefinito.


0

Il codice sottostante viene utilizzato per selezionare il primo elemento ed evidenziare il primo elemento selezionato nel menu.

onNavigationItemSelected(mNavigationView.getMenu().getItem(0).setChecked(true));

Potete per favore dirmi come e dove questo onNavigationItemSelected è accessibile? Fornisci un esempio di codice più completo.
Kilokahn,


-1

Per qualche motivo è preferibile trovare MenuItem usando gli ID.

drawer.getMenu().findItem(R.id.action_something).setChecked(true);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.