Tiroir de navigation: comment définir l'élément sélectionné au démarrage?


229

Mon code fonctionne parfaitement: chaque fois qu'un élément du tiroir de navigation est cliqué, l'élément est sélectionné.

Bien sûr, je veux démarrer l'application avec un fragment par défaut (home), mais le tiroir de navigation n'a pas l'élément sélectionné. Comment puis-je sélectionner cet élément par programme?

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;
[...]

Je pense que je dois modifier ici:

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

Ou onCreateau démarrage de l'application avec FragmentTransaction.

Merci pour votre soutien.


L'une des réponses déclenche-t-elle une onNavigationItemSelectedaction pour l'ID sélectionné?
Prabs

Réponses:


478

Utilisez le code ci-dessous:

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

Appelez cette méthode après avoir appelé setNavDrawer();

La getItem(int index)méthode obtient le MenuItempuis vous pouvez l'appeler setChecked(true);dessus MenuItem, tout ce qu'il vous reste à faire est de trouver quel index d'élément possède la valeur par défaut et de remplacer le 0 par cet index.

Vous pouvez sélectionner (mettre en surbrillance) l'élément en appelant

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

Voici un lien de référence: http://thegeekyland.blogspot.com/2015/11/navigation-drawer-how-set-selected-item.html

EDIT N'a pas fonctionné sur nexus 4, supporte la révision de la bibliothèque 24.0.0. Je recommande l'utilisation

navigationView.setCheckedItem(R.id.nav_item);

répondu par @kingston ci-dessous.


65
Ajout des bibliothèques de support Android v23 setCheckedItem (int id).
Markus Rubey

1
@MarkusRubey même après avoir défini setCheckedItem Je ne parviens pas à mettre en surbrillance l'élément sélectionné. Pourriez-vous nous dire la raison possible?
Dexto

3
Pas travaillé pour moi! Lorsque la méthode onNavigationItemSelected est appelée pour d'autres options dans le tiroir du menu de navigation, l'élément initial appelé "vérifié" conserve toujours son état. Lorsque j'utilise 'navigationView.setCheckedItem (id);' a parfaitement fonctionné! Après cela, il doit appeler la méthode 'navigationView.getMenu () performIdentifierAction (R.id.nav_market, 0);' pour effectuer la sélection de l'élément souhaité.
GFPF

3
Aucune des méthodes mentionnées n'a fonctionné pour moi pour une raison quelconque. Mais faire navigationView.post(new Runnable() { navigationView.setCheckedItem(...) })- a fonctionné.
dimsuz

1
Vous essayez probablement de modifier l'élément coché à partir d'un thread différent du thread principal :)
Arlind

105

Vous pouvez également appeler:

navigationView.setCheckedItem(id);

Cette méthode a été introduite dans l'API 23.0.0

Exemple

<?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>

Remarque: android:checkableBehavior="single"

Voir aussi ceci


1
même après avoir défini setCheckedItem, je ne parviens pas à mettre en surbrillance l'élément sélectionné. Pourriez-vous nous dire la raison possible?
Dexto

3
@DeepeshDoshi Veuillez vous assurer que vous avez un comportement vérifiable.
Jared Burrows

1
il devrait navigationView.setCheckedItem (R.id.menu_nav_home) pour sélectionner le menu d'accueil
jaga

pour un article individuel, ajoutez-le simplement android:checkable="true", il ne sera pas vérifié par vous-même
sud007

Assurez-vous également que vous n'appelez pas cette méthode depuis avec navItemSelecteListenercar l'élément est sélectionné après le retour de cette méthode.
mallaudin

47

Pour moi, ces deux méthodes n'ont pas fonctionné:

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

Essayez celui-ci, cela fonctionne pour moi.

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


2
Merci pour cette astuce. Les méthodes ci-dessus sont en fait correctes, mais le problème est différent: si vous les utilisez, onNavigationItemSelected ne sera pas appelé, seul l'élément de menu sera vérifié. Nous devons donc appeler les deux méthodes.
user1209216

2
onNavigationItemSelected (navView.getMenu (). getItem (0)); ou onNavigationItemSelected (navView.getMenu (). getItem (R.id.nav_profile)); les deux fonctionnaient pour moi, getitem au lieu de finditem.
Harsh Dalwadi

30

Exemple ( 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
C'est une façon de le faire, j'aime ça. Cependant, les réponses uniquement codées sont souvent découragées. Je voudrais modifier votre réponse pour expliquer un peu le code, par exemple pourquoi vous utilisez performIdentifierActionet ce qui se passe onNavigationItemSelected. Pour vous, cela peut sembler simple, mais un nouveau développeur peut avoir du mal à comprendre votre code.
AdamMc331

@ McAdam331 Bien sûr, n'hésitez pas, il est à moitié passé ici aujourd'hui et n'a pas eu le temps d'écrire plus en détail.
GFPF

25

Il y a toujours des problèmes avec les bibliothèques de support "oh so great" de Google. Si vous souhaitez vérifier un élément sans rétrograder la version de vos bibliothèques de support, définissez simplement checkable avant de définir l'état vérifié.

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

Cela peut également fonctionner si vous définissez checkable dans les fichiers xml du menu



9

L'API 23 fournit la méthode suivante:

navigationView.setCheckedItem(R.id.nav_item_id);

Cependant, pour une raison quelconque, cette fonction n'a pas provoqué l'exécution du code derrière l'élément de navigation. La méthode met certainement en évidence l'élément dans le tiroir de navigation, ou le `` vérifie '', mais il ne semble pas appeler le OnNavigationItemSelectedListenerrésultat dans un écran vide au démarrage si votre écran de démarrage dépend des sélections du tiroir de navigation. Il est possible d'appeler manuellement l'auditeur, mais cela semble hacky:

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

Le code ci-dessus suppose:

  1. Vous avez implémenté NavigationView.OnNavigationItemSelectedListenerdans votre activité
  2. Vous avez déjà appelé:
    navigationView.setNavigationItemSelectedListener(this);
  3. L'élément que vous souhaitez sélectionner se trouve en position 0

6

Pour cela, vous devez appeler 2 fonctions:

Premièrement: pour échanger les commandes que vous avez implémentées dans l' onNavigationItemSelectedécouteur:

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

Deuxièmement: pour changer l'état de l'élément de menu du tiroir de navigation sur sélectionné (ou coché):

navigationView.setCheckedItem(R.id.nav_camera);

J'ai appelé les deux fonctions et cela a fonctionné pour moi.


5

Le code suivant ne fera que sélectionner l'élément de menu:

navigationView.setCheckedItem(id);

Pour sélectionner et ouvrir l'élément de menu, ajoutez le code suivant après la ligne ci-dessus.

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


4

Ceci est ma solution, très simple.

Voici mon fichier 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>

Le menu ci-dessus mettra en surbrillance le premier élément du menu. La ligne ci-dessous fera quelque chose (par exemple: afficher le premier fragment, etc.). REMARQUE: écrivez après «configurer votre code de tiroir»

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

4

Le moyen le plus simple est de le sélectionner dans xml comme suit,

<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" />

Notez la ligne android:checked="true"


1
À mon avis, la meilleure réponse, la cause utilise la logique fournie par défaut par Android. Voté comme meilleur seulement est meilleur, si le menu utilise la disposition et généré par l'adaptateur et non le fichier xml du menu.
Andris

1
C'est la meilleure réponse
Ganesh Chowdhary Sadanala

2

Créez d'abord des couleurs pour l'élément sélectionné. Voici https://stackoverflow.com/a/30594875/1462969 bon exemple. Il vous aide à changer la couleur de l'icône. Pour changer l'arrière-plan de tous les éléments sélectionnés, ajoutez dans votre fichier values ​​\ style.xml ce

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

Où selectable_item_background doit être déclaré dans 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>

Où la couleur peut être déclarée dans style.xml

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

Et après ça

   // 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;
            }
        });

Comme vous le voyez, j'ai utilisé ce mainNavigationMenu_.getMenu (). FindItem (itemId) .setChecked (true); pour définir l'élément sélectionné. Navigation ici

 <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"/>

J'aime cette méthode, je l'utilise actuellement dans mon propre projet. Il peut être utile d'inclure le @color/state_listcode dans votre réponse. Par curiosité, où avez-vous obtenu la convention de dénomination pour mettre un trait de soulignement à la fin du nom de la variable? Je n'ai jamais vu cette approche.
AdamMc331

Je pense que vous voulez peut-être menuItem.getItemId()au lieu deitemId
Craig Russell

2

Lorsque vous utilisez BottomNavigationViewles autres réponses telles que navigationView.getMenu().getItem(0).setChecked(true);et navigationView.setCheckedItem(id);ne fonctionnera pas, appeler setSelectedItemIdfonctionne:

    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

Faire un sélecteur pour un article individuel du tiroir de navigation

<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>

Apportez quelques modifications à votre 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

sur votre activité (derrière le tiroir):

@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));
}

et

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

et dans votre 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>

donc le premier menu est mis en surbrillance et affiché comme menu par défaut.


0

Le code ci-dessous est utilisé pour sélectionner le premier élément et mettre en surbrillance le premier élément sélectionné dans le menu.

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

Pouvez-vous s'il vous plaît me dire comment et où ce onNavigationItemSelected est accessible? Veuillez fournir un exemple de code plus complet.
kilokahn

0

tu peux le faire, nav_view.getMenu().findItem(R.id.menutem).setChecked(true)


-1

Pour une raison quelconque, il est préférable de trouver le MenuItem en utilisant les ID.

drawer.getMenu().findItem(R.id.action_something).setChecked(true);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.