Cajón de navegación: configurado como siempre abierto en tabletas

Estoy usando el patrón de Cajón de navegación de la biblioteca de soporte: http://developer.android.com/training/implementing-navigation/nav-drawer.html

Estaba intentando configurarlo como siempre abierto en la tableta (como un menú lateral)

enter image description here

¿Es posible algo con la implementación actual, o tenemos que crear un nuevo diseño y una nueva estructura con Listview en lugar de reutilizar el mismo código?

    Partiendo de la respuesta de CommonsWare, puedes hacer esto con un par de ajustes. El primero es establecer las siguientes tres líneas:

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

    El color drawerNoShadow solo puede ser un color sin alfa (como 0x00000000). Eso te da un cajón abierto sin superposición de fondo.

    Lo segundo que debe hacer es ajustar el valor de padding_left de su FrameLayout. Para este propósito, puede configurar una dimensión para controlar esto (0dp por defecto) – en este ejemplo R.dimen.drawerContentPadding. También necesitará un valor R.dimen.drawerSize que será el ancho de DrawerLayout.

    Esto le permite verificar el valor de rellenoLeft de FrameLayout para llamar a esas líneas.

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

    A continuación, puede ajustar toda la funcionalidad que no desea habilitar en una if(!isDrawerLocked) . Esto incluirá:

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

    Por último, necesita configurar diseños alternativos para las vistas con un cajón estático. Un ejemplo es:

           

    La belleza aquí es que puede controlar toda la lógica configurando archivos dimen.xml alternativos para los dispositivos a los que desea apuntar y lo único que necesita cambiar es el valor de drawerContentPadding y ofrecer los diseños modificados.

    NOTA: Terminé utilizando margin_left en lugar de padding_left ya que en el nuevo diseño superpone el cajón. Vea una publicación más detallada en el blog sobre la técnica en http://derekrwoods.com/2013/09/creating-a-static-navigation-drawer-in-android/

    Pruebe setDrawerLockMode() para bloquear el cajón abierto en dispositivos de pantalla grande.

    Como noté en un comentario, no creo que DrawerLayout esté diseñado para su escenario (aunque no es una mala idea, en mi humilde opinión). Utilice un diseño diferente que aloje el mismo ListView y contenido, o tal vez descargue y modifique su propia copia de DrawerLayout que, en dispositivos de pantalla grande, desliza el contenido cuando se abre en lugar de superponerlo.

    Las respuestas anteriores son buenas, pero tuve problemas al implementarlas en mi proyecto, por lo que quiero compartir mi solución. En primer lugar, debemos definir un cajón personalizado:

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

    Luego lo colocamos en un diseño de actividad básico (sin diseños arbitrarios de respuestas anteriores) como este:

          

    El relleno de contenido aquí es 0dp en orientación vertical y aproximadamente 300dp en el paisaje para NavigationView (calculado empíricamente). Los definimos en carpetas de values apropiados:

    values/dimens.xml

     0dp 

    values-land/dimens.xml

     300dp 

    Finalmente, bloqueamos el cajón en la actividad:

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

    No tiene que ser tan complicado ya que hay un método limpio y directo para lograrlo.

    Paso 1

    Simplemente cree un archivo de diseño alternativo similar a este para tabletas y colóquelo en el directorio de recursos layout-w600dp-land .

     < ?xml version="1.0" encoding="utf-8"?>        

    Paso 2

    Ahora no tenemos que mostrar el botón de alternar del cajón ni cerrar el cajón cuando un elemento hace clic en los dispositivos que no son tableta.

    Paso 2.1

    Para hacerlo posible, es necesario verificar si el dispositivo es una tableta o no tableta en el tiempo de ejecución.

    Agregue el siguiente contenido a un nuevo archivo de recursos de valor en el directorio de valores y config_ui.xml nombre config_ui.xml

     < ?xml version="1.0" encoding="utf-8"?>  false  

    Eso fue para dispositivos que no son tabletas. Para dispositivos de tableta, crea otro con el mismo nombre y values-w600dp-land en values-w600dp-land .

     < ?xml version="1.0" encoding="utf-8"?>  true  

    Cree un nuevo campo en la clase de la actividad a la que pertenece el cajón como private boolean isDrawerFixed; e inicializarlo como isDrawerFixed = getResources().getBoolean(R.bool.isDrawerFixed); .

    Paso 2.2

    ¡Todo listo! Ahora podemos verificar si el dispositivo es una tableta o no es como if (isDrawerFixed){} .

    Habrá algo como esto.

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

    Para configurar el botón de alternar en la barra de acciones. Envuélvalo dentro de if (!isDrawerFixed) {}

    Para cerrar el cajón cuando se hace clic en un elemento, habrá algo como esto.

     drawer.closeDrawer(GravityCompat.START); 

    Envuélvalo en if (!isDrawerFixed) {} también.

    Como referencia, he incluido capturas de pantalla de una aplicación en la que utilicé este método.

    enter image description here