Tiroir de navigation: réglé comme toujours ouvert sur les tablettes

J’utilise le modèle de tiroir de navigation de la bibliothèque de support: http://developer.android.com/training/implementing-navigation/nav-drawer.html

J’essayais de le définir comme toujours ouvert sur la tablette (en tant que menu secondaire)

entrer la description de l'image ici

Est-ce quelque chose de possible avec l’implémentation actuelle ou devons-nous créer une nouvelle disposition et une nouvelle structure avec une vue Listview au lieu de réutiliser le même code?

Basé sur l’idée d’appareils plus grands pourraient avoir différents fichiers de mise en page, j’ai créé le projet suivant.

https://github.com/jiahaoliuliu/ABSherlockSlides

HighLights :

Le tiroir d’un grand appareil étant toujours visible, il n’est pas nécessaire d’avoir un tiroir. Au lieu de cela, un LinearLayout avec deux éléments portant le même nom suffira.

    

Comme nous n’avons pas le tiroir dans le fichier de mise en page, lorsque l’application essaie de trouver l’élément dans la mise en page, elle renvoie null. Il n’est donc pas nécessaire d’avoir un booléen supplémentaire pour voir quelle mise en page utilise.

 DrawerLayout mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout); if (mDrawerLayout != null) { // Set a custom shadow that overlays the main content when the drawer opens mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); // Enable ActionBar app icon to behave as action to toggle nav drawer getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); // ActionBarDrawerToggle ties together the proper interactions // between the sliding drawer and the action bar app icon mDrawerToggle = new ActionBarDrawerToggle( this, mDrawerLayout, R.drawable.ic_drawer, R.ssortingng.drawer_open, R.ssortingng.drawer_close) { public void onDrawerClosed(View view) { super.onDrawerClosed(view); } public void onDrawerOpened(View drawerView) { // Set the title on the action when drawer open getSupportActionBar().setTitle(mDrawerTitle); super.onDrawerOpened(drawerView); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); } 

Voici l’exemple pour l’utiliser comme booléen.

 @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); if (mDrawerLayout != null) { mDrawerToggle.syncState(); } } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (mDrawerLayout != null) { // Pass any configuration change to the drawer toggles mDrawerToggle.onConfigurationChanged(newConfig); } } 

En vous appuyant sur la réponse de CommonsWare, vous pouvez le faire avec quelques ajustements. Le premier consiste à définir les trois lignes suivantes:

 drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN); drawerLayout.setScrimColor(getResources().getColor(R.color.drawerNoShadow)); isDrawerLocked = true; 

La couleur drawerNoShadow peut simplement être une couleur sans alpha (comme 0x00000000). Cela vous donne un tiroir ouvert sans recouvrement de fond.

La deuxième chose à faire est d’ajuster la valeur padding_left de votre FrameLayout. Pour cela, vous pouvez configurer une dimension pour contrôler ceci (0dp par défaut) – dans cet exemple R.dimen.drawerContentPadding. Vous aurez également besoin d’une valeur R.dimen.drawerSize qui sera la largeur de DrawerLayout.

Cela vous permet de vérifier la valeur paddingLeft du FrameLayout pour appeler ces lignes.

 FrameLayout frameLayout = (FrameLayout)findViewById(R.id.content_frame); if(frameLayout.getPaddingLeft() == (int)getResources().getDimension(R.dimen.drawerSize) { drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN); drawerLayout.setScrimColor(getResources().getColor(R.color.drawerNoShadow)); isDrawerLocked = true; } 

Vous pouvez ensuite envelopper toutes les fonctionnalités que vous ne souhaitez pas activer dans une if(!isDrawerLocked) . Cela comprendra:

  • drawerLayout.setDrawerListener(drawerToggle);
  • getActionBar().setDisplayHomeAsUpEnabled(true);

Enfin, vous devez configurer d’autres dispositions pour les vues avec un tiroir statique. Un exemple est:

       

La beauté ici est que vous pouvez ensuite contrôler toute la logique en configurant des fichiers dimen.xml alternatifs pour les périphériques que vous souhaitez cibler. La seule chose que vous devez changer est la valeur de drawerContentPadding et proposer les mises en page modifiées.

REMARQUE: j’ai fini par utiliser margin_left au lieu de padding_left car dans la nouvelle présentation, il recouvre le tiroir. Voir un blog plus détaillé sur la technique à l’ adresse http://derekrwoods.com/2013/09/creating-a-static-navigation-drawer-in-android/

Essayez setDrawerLockMode() pour verrouiller le tiroir ouvert sur les périphériques grand écran.

Comme je l’ai noté dans un commentaire, je ne pense pas que DrawerLayout soit conçu pour votre scénario (même si ce n’est pas une mauvaise idée, à DrawerLayout avis). Utilisez soit une mise en page différente qui héberge le même ListView et le même contenu, ou peut-être téléchargez et modifiez votre propre copie de DrawerLayout qui, sur les périphériques grand écran, fait glisser le contenu lorsqu’il est ouvert plutôt que de le chevaucher.

Les réponses précédentes sont bonnes, mais j’ai rencontré des problèmes lors de leur mise en œuvre dans mon projet, alors je veux partager ma solution. Tout d’abord, nous devons définir un tiroir personnalisé:

 public class MyDrawerLayout extends DrawerLayout { private boolean m_disallowIntercept; public MyDrawerLayout (Context context) { super(context); } @Override public boolean onInterceptTouchEvent(final MotionEvent ev) { // as the drawer intercepts all touches when it is opened // we need this to let the content beneath the drawer to be touchable return !m_disallowIntercept && super.onInterceptTouchEvent(ev); } @Override public void setDrawerLockMode(int lockMode) { super.setDrawerLockMode(lockMode); // if the drawer is locked, then disallow interception m_disallowIntercept = (lockMode == LOCK_MODE_LOCKED_OPEN); } } 

Ensuite, nous le mettons dans une disposition d’activité de base (sans disposition arbitraire des réponses précédentes) comme ceci:

      

Le remplissage de contenu est ici de 0dp en orientation portrait et d’environ 300dp en mode paysage pour NavigationView (calculé empiriquement). Nous les définissons dans des dossiers de values appropriés:

values/dimens.xml

 0dp 

values-land/dimens.xml

 300dp 

Enfin, nous verrouillons le tiroir dans l’activité:

  if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN); mDrawerLayout.setScrimColor(0x00000000); // or Color.TRANSPARENT isDrawerLocked = true; } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); mDrawerLayout.setScrimColor(0x99000000); // default shadow isDrawerLocked = false; } 

Cela ne doit pas être compliqué car il existe une méthode simple et directe pour y parvenir.

Étape 1

Il vous suffit de créer un autre fichier de présentation similaire à celui des tablettes et de le placer dans le répertoire de ressources layout-w600dp-land .

         

Étape 2

Maintenant, nous n’avons pas besoin d’afficher le bouton de basculement du tiroir ou de fermer le tiroir lorsqu’un élément a cliqué sur les périphériques non-tablette.

Étape 2.1

Pour que cela soit possible, il est nécessaire de vérifier si l’appareil est une tablette ou une tablette lors de l’exécution.

Ajoutez le contenu suivant à un nouveau fichier de ressources de valeur dans le répertoire de valeurs et nommez-le config_ui.xml

   false  

C’était pour les appareils autres que les tablettes. Pour les tablettes, créez-en une autre avec le même nom et placez-la dans des values-w600dp-land .

   true  

Créez un nouveau champ dans la classe de l’activité à laquelle appartient le tiroir en tant que private boolean isDrawerFixed; et l’initialiser comme isDrawerFixed = getResources().getBoolean(R.bool.isDrawerFixed); .

Étape 2.2

Tous ensemble! Maintenant, nous pouvons vérifier si le périphérique est un if (isDrawerFixed){} déposé ou non, comme if (isDrawerFixed){} .

Il y aura quelque chose comme ça.

 ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.ssortingng.navigation_drawer_open, R.ssortingng.navigation_drawer_close); drawer.addDrawerListener(toggle); toggle.syncState(); 

Pour configurer le bouton bascule sur la barre d’action. Enveloppez-le dans un if (!isDrawerFixed) {}

Pour fermer le tiroir lorsqu’un élément est cliqué, il y aura quelque chose comme ceci.

 drawer.closeDrawer(GravityCompat.START); 

Enveloppez-le dans un if (!isDrawerFixed) {} aussi.

Pour référence, j’ai inclus des captures d’écran d’une application dans laquelle j’ai utilisé cette méthode.

entrer la description de l'image ici