Désactiver le tiroir de navigation, basculer en fragments le bouton d’accueil / indicateur de montée

La mise en place

J’ai une activité dont contentView est une instance de DrawerLayout , qui dispose d’un tiroir de navigation avec un indicateur de tiroir affiché dans la barre d’action. L’activité contient un Fragment , appelons-le ListFragment , qui contient une liste d’options. Lorsque vous cliquez sur une option, je remplace le ListFragment par un DetailFragment .

Architecture de l'application

À ce stade, je voudrais afficher une option de navigation “up” au lieu de l’indicateur de tiroir de navigation. Je peux afficher l’icône “haut” si je désactive l’indicateur de tiroir en appelant mDrawerToggle.setDrawerIndicatorEnabled(false) , mais cela ne supprime que l’icône du tiroir – il ne supprime pas la fonctionnalité – c’est-à-dire lorsque je clique sur le bouton caret, le tiroir de navigation est toujours ouvert.

De plus, dans ces sous-vues, je souhaite désactiver l’ouverture du tiroir en faisant glisser depuis le bord de l’écran. J’ai essayé de le faire en appelant setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) mais il ne semble pas avoir désactivé cette fonctionnalité.

J’ai essayé d’étendre la classe ActionBarDrawerToggle pour empêcher l’ouverture du tiroir lorsque l’utilisateur clique sur l’indicateur. Cependant, tout ce qui se produit est que l’action de substitution (la navigation vers le haut) est effectuée, mais le tiroir s’ouvre toujours .

J’ai également implémenté les étapes de la section Basculer entre l’image de Android Navigation Drawer et Up caret lors de l’utilisation de fragments . Cela fonctionne dans la mesure où l’affichage du caret va, mais en dépit de la fonctionnalité du bouton haut, le menu s’ouvre toujours (l’application retourne en arrière – elle ouvre également le tiroir).

Question

Donc, longue histoire courte: y a-t-il une façon (de préférence propre et élégante, mais à ce stade je vais y aller avec du piratage) pour réaliser ces choses lorsque ma racine de mise en page est un DrawerLayout :

  1. Remplacez l’indicateur de tiroir par un mDrawerToggle.setDrawerIndicatorEnabled(false)) “up” (provisoirement réalisable via mDrawerToggle.setDrawerIndicatorEnabled(false))
  2. Empêcher le tiroir de s’ouvrir lorsque l’utilisateur clique sur le curseur, et remplacer par la même occasion ma propre fonctionnalité “up”
  3. Empêchez le tiroir de s’ouvrir lorsque je le traîne du bord de l’écran.

modifier

D’accord, il semble que si je remplace à la fois ActionBarDrawerToggle AND onOptionsItemSelected , le menu ne s’ouvre pas lorsque je clique sur le curseur. Mais il s’ouvre toujours si je traîne du bord. Aidez-moi!

Petit code

 public void setDrawerState(boolean isEnabled) { if ( isEnabled ) { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); drawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED); drawerToggle.setDrawerIndicatorEnabled(true); drawerToggle.syncState(); } else { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); drawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); drawerToggle.setDrawerIndicatorEnabled(false); drawerToggle.syncState(); } } 

Ce n’est qu’une partie de la solution à laquelle je suis arrivé, mais c’était assez difficile de trouver ce bogue, alors je pars ici pour la postérité.

Voici comment je définissais le ListView pour mon tiroir de navigation:

  

Même après avoir appelé setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) je pouvais toujours ouvrir le tiroir.

Cependant, après avoir modifié le layout_gravity pour "start" ce problème semble être résolu.

J’ai été en mesure de reproduire ce problème dans un exemple, une application de navigation-tiroir uniquement, il semble donc que ce soit un problème reproductible qui ne soit pas unique à ma situation.

S’appuyant sur la réponse de sonida. Après avoir appelé setDrawerIndicatorEnabled (false), onNavigateUp n’était toujours pas appelé. Donc, je viens de créer un nouvel onClickListener qui l’a appelé:

 public void setDrawerState(boolean isEnabled) { if ( isEnabled ) { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); drawerToggle.setDrawerIndicatorEnabled(true); drawerToggle.syncState(); } else { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); drawerToggle.setDrawerIndicatorEnabled(false); drawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onSupportNavigateUp(); } }); drawerToggle.syncState(); } } 

aussi je pense

 drawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED); 

a été déprécié, mais cela fonctionne bien sans elle.

Vous devez désactiver le balayage et désactiver le bouton d’accueil de la barre d’action:

Utilisez le code ci-dessous qui repose sur le code déjà donné pour désactiver le balayage

  public void setDrawerState(boolean isEnabled) { if ( isEnabled ) { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED); mDrawerToggle.setDrawerIndicatorEnabled(true); mDrawerToggle.syncState(); getActivity().getActionBar().setHomeButtonEnabled(true); } else { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); mDrawerToggle.setDrawerIndicatorEnabled(false); mDrawerToggle.syncState(); getActivity().getActionBar().setHomeButtonEnabled(false); } } 

S’appuyant sur la réponse de @sonida Et après avoir utilisé les réglages fournis par @ luca992 et @jai.

J’ai essayé ci-dessus les codes suggérés Mais la flèche “haut” ou “Retour” dans la partie gauche de la barre d’action ne s’affichait tout simplement pas dans mon application. Mais heureusement, j’ai été capable de résoudre ce problème.

J’ai dû append cette ligne de code supplémentaire dans setNavigationDrawerState () [Ref: android.support.v7.app.ActionBarDrawerToggle.setHomeAsUpIndicator ]

toggle.setHomeAsUpIndicator (R.drawable.ic_keyboard_backspace_white_24dp);

J’ai téléchargé le fichier pouvant être tiré: ic_keyboard_backspace_white_24dp de Material.io

Voici le code complet:

MainActivity.java -> onCreate ()

 DrawerLayout drawer; ActionBarDrawerToggle toggle; @Override protected void onCreate(Bundle savedInstanceState) { // Start: Code automatically generated by Android Studio super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); drawer = (DrawerLayout) findViewById(R.id.drawer_layout); toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.ssortingng.navigation_drawer_open, R.ssortingng.navigation_drawer_close); drawer.setDrawerListener(toggle); toggle.syncState(); // End: Code automatically generated by Android Studio // I had to add this listener as the "back" arrow was totally unresponsive // Thanks to @luca992 toggle.setToolbarNavigationClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onBackPressed(); } }); // Start: Code automatically generated by Android Studio NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); // End: Code automatically generated by Android Studio // More custom code for other stuff // ... } 

MainActivity.java -> setNavigationDrawerState ()

 public void setNavigationDrawerState(boolean isEnabled) { if ( isEnabled ) { drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); toggle.setDrawerIndicatorEnabled(true); toggle.syncState(); } else { drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); toggle.setDrawerIndicatorEnabled(false); // the extra line of code goes here toggle.setHomeAsUpIndicator(R.drawable.ic_keyboard_backspace_white_24dp); toggle.syncState(); } 

MainActivity.java -> onBackPressed ()

 @Override public void onBackPressed() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else if(getSupportFragmentManager().getBackStackEntryCount() > 0){ getSupportFragmentManager().popBackStack(); }else { super.onBackPressed(); } } 

MainActivity.java -> startFragment () [fonction factice par exemple]

 public void startFragment(){ MyFrag myFrag = new MyFrag(); getSupportFragmentManager() .beginTransaction() .replace(R.id.frag_container ,myFrag) .addToBackStack(null) .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) .commit(); } 

MyFrag.java -> onViewCreated ()

 @Override public void onViewCreated (View view, Bundle savedInstanceState){ super.onViewCreated(view, savedInstanceState); // Say, using an implemented interface Make call to MainActivitiy's setNavigationDrawerState() passing false // setNavigationDrawerState(false) // ... } 

MyFrag.java -> onDestroyView ()

 @Override public void onDestroyView(){ // Say, using an implemented interface Make call to MainActivitiy's setNavigationDrawerState() passing true // setNavigationDrawerState(true) super.onDestroyView(); }