Cómo configurar el cajón de navegación para que se abra de derecha a izquierda


85

En primer lugar, sé que esta pregunta apareció aquí antes, pero después de intentar mucho, todavía no tuve éxito. Estoy trabajando en el ejemplo del sitio de desarrolladores de Android .

Estoy tratando de configurar el menú para que se abra de derecha a izquierda en lugar de cómo se implementa en el ejemplo (de izquierda a derecha). Además, quiero mover el botón de menú abierto al lado derecho de la barra de acción. También rojo algunas respuestas aquí, por ejemplo en esta respuesta .

Intento cambiar la gravedad de las vistas y los diseños, pero aparece el error:

no se encontró vista de cajón con gravedad absoluta IZQUIERDA

¿Puede ayudarme a averiguar cuál es el problema en mi código y qué debo cambiar para configurar el menú para que se abra desde la derecha y para mover el botón de la barra de acción hacia la derecha?

el código xml está aquí:

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_gravity="right"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/content_frame"
        android:layoutDirection="rtl"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

    <ListView android:id="@+id/left_drawer"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="right"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="10dp"
        android:background="#111"/>

</android.support.v4.widget.DrawerLayout>


Eche un vistazo a github.com/Ali-Rezaei/SlidingDrawer, que permite deslizar desde cualquier lado unas pocas líneas de código.
Ali

Respuestas:


155

En su diseño principal, establezca su ListViewgravedad a la derecha:

android:layout_gravity="right" 

También en tu código:

mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
            R.drawable.ic_drawer, R.string.drawer_open,
            R.string.drawer_close) {

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item != null && item.getItemId() == android.R.id.home) {
            if (mDrawerLayout.isDrawerOpen(Gravity.RIGHT)) {
                mDrawerLayout.closeDrawer(Gravity.RIGHT);
            } 
            else {
                mDrawerLayout.openDrawer(Gravity.RIGHT);
            }
        }
        return false;
    }
};

espero que funcione :)


2
@Rudi: ¿Sabes la respuesta de la segunda parte? Me refiero a cómo hacer la barra de acción de derecha a izquierda. (El cajón y la dirección del icono de navegación hacia arriba también cambian)
Alireza Farahani

@alireza, ¿por qué no usas una barra de acciones personalizada?
Rudi

@Rudi: ¿Te refieres al setCustomViewmétodo? En caso afirmativo, ¿le importaría pegar algunos enlaces que muestren cómo hacerlo?
Alireza Farahani

@alireza Quiero decir, en lugar de usar la barra de acciones en la parte superior de su vista, cree su barra de acciones personalizada en su xml principal y configúrela como desee.
Rudi

@Rudi: Pero entonces, ¿cómo puedo lograr el mismo comportamiento como navegación hacia arriba y animación de apertura y cierre de cajón? ¿Tengo que implementarlos desde cero?
Alireza Farahani

62

Agregue este código al manifiesto:

<application android:supportsRtl="true">

y luego escribe este código en Oncreate:

getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);

Esto funciona para mi. ;)


1
esta es la respuesta correcta, solo configure la gravedad de su vista de lista para comenzar, luego use este código, todo debería estar bien
Mahdi Giveie

9
Está funcionando, sin embargo, setLayoutDirection (View.LAYOUT_DIRECTION_RTL) es para API por encima de 17, por lo que no puede usar esto para api inferior
Milad

6
¿No cambiará todo el diseño de la actividad, incluso toStartOf / toEndOf, etc ...?
TWiStErRob

13
Esta es una respuesta incorrecta. Cambia el diseño completo de la actividad de derecha a izquierda.
Tarun

1
Pensé que es una solución rápida pero no correcta.
sidhanshu

37

SOLUCIÓN


your_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="end">

    <include layout="@layout/app_bar_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:itemTextColor="@color/black"
        app:menu="@menu/activity_root_drawer" />

</android.support.v4.widget.DrawerLayout>

YourActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
//...
toolbar = (Toolbar) findViewById(R.id.toolbar);

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.setDrawerListener(toggle);
toggle.syncState();

toolbar.setNavigationOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (drawer.isDrawerOpen(Gravity.RIGHT)) {
                drawer.closeDrawer(Gravity.RIGHT);
            } else {
                drawer.openDrawer(Gravity.RIGHT);
            }
        }
    });
//...
}

2
Funciona genial. Pero el icono de la barra de herramientas sigue apareciendo a la izquierda. ¿Cómo llevar el icono del botón de alternancia también a la derecha?
Darush

Le di android: layout_gravity = "end" tanto para Drawerlayout como para NavigationView, funciona bien.
varotariya vajsi

toolbar.setNavigationOnClickListenerrequiere un nivel mínimo de API 21 :(
SepJaPro2.4

@ SepJaPro2.4 sí, pero From August 2018, new apps must target at least Android 8.0 (API level 26). From November 2018, app updates must target Android 8.0 (API level 26).(Google)
Volodymyr Kulyk

2
Agregue android: layoutDirection = "rtl" en su AppBarLayout XML para configurar el botón de alternancia a la derecha
Terranology

4

Esta respuesta es útil para configurar la navegación abierta de derecha a izquierda, pero no tiene una solución para configurar su icono en el lado derecho. Este código puede solucionarlo. Si le da drawercomo primer parámetro y ViewCompat.LAYOUT_DIRECTION_RTLcomo segundo parámetro, el diseño de entrada se establecerá en RTL. Es una solución rápida y simple, pero no creo que pueda ser una solución correcta para quienes solo quieren configurar el menú para que se abra de derecha a izquierda y configurar su ícono para que esté en el lado derecho. (Aunque, depende de su propósito). Sin embargo, sugiero dar el en toolbarlugar del drawer. De esta forma, solo la barra de herramientas se ha convertido en RTL. Entonces creo que la combinación de estas 2 respuestas puede hacer exactamente lo que quieras.

Según estas descripciones, su código debería ser así:

(Agregue estas líneas al método onCreate)

final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); // Set it final to fix the error that will be mention below.

    ViewCompat.setLayoutDirection(toolbar, ViewCompat.LAYOUT_DIRECTION_RTL);

    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (drawer.isDrawerOpen(Gravity.RIGHT))
                drawer.closeDrawer(Gravity.RIGHT);
            else
                drawer.openDrawer(Gravity.RIGHT);
        }
    });

Tenga en cuenta que debe hacer que el cajón sea final, de lo contrario obtendrá este error:

Se accede a la variable 'cajón' desde dentro de la clase interna, debe declararse final

Y no olvides usar en endlugar de starten el onNavigationItemSelectedmétodo:

drawer.closeDrawer(GravityCompat.END);

y en su activity_main.xml

<android.support.v4.widget.DrawerLayout 
   android:id="@+id/drawer_layout"
   tools:openDrawer="end">

   <android.support.design.widget.NavigationView
      android:id="@+id/nav_view"
      android:layout_gravity="end"/>
</android.support.v4.widget.DrawerLayout>

3

Aquí está la documentación en el cajón y parece que puede configurarlo para extraerlo desde la izquierda o la derecha.

El posicionamiento y el diseño del cajón se controlan mediante el atributo android: layout_gravity en las vistas secundarias correspondientes al lado de la vista desde el que desea que emerja el cajón: izquierda o derecha. (O comenzar / finalizar en versiones de plataforma que admiten la dirección de diseño).

http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html


Vi esta respuesta antes y también la mencioné en mi pregunta.
galvan

Bueno. Intente usar en endlugar de righten la gravedad. EDITAR: quitar android:layout_gravity="right"del android.support...DrawerLayouty cambiar android:layout_gravity="right"al android:layout_gravity="end"interiorListView
KickAss

1
Sigo recibiendo el error: no se encontró ninguna vista de cajón con gravedad absoluta IZQUIERDA. Agregué al manifiesto android: supportsRtl = "true", y en el xml debajo del drawerLayout agregué android: layoutDirection = "rtl", y luego el menú se abre a la derecha, pero ahora no se cierra cuando hago clic en el botón de menú (en la barra de acción) cuando hago clic en cualquier elemento de la lista, o fuera de la lista, se cierra pero no cuando hago clic en el botón de menú en la barra de acción, ¿alguna idea de por qué?
galvan

No estoy del todo seguro, pero ... como la dirección y la posición del cajón ahora han cambiado, en su Actividad, según el ejemplo de Android, debe tener el método de interruptor de palanca / oyente de botón, verifique si es necesario modificado para que sepa cerrar moviéndolo de derecha a izquierda. Podría estar pensando que mantener en el menú ya está a la izquierda (es decir, oculto) por lo que no se cerrará (si eso tiene sentido) ...
KickAss

Chicos, también estoy haciendo el mismo tipo de cosas, pero si uso laoutDirection = "rtl", entonces tengo que cambiar minSdk a 17, pero mi aplicación necesita ser compatible con API nivel 10. ¿Pueden ayudarme para que mi aplicación admita API 10?
Aditya

3

Eche un vistazo a esto: deslice ExpandableListView en el formulario DrawerLayout de derecha a izquierda

Supongo que tiene implementado ActionBarDrawerToggle, el truco es anular el onOptionsItemSelected(MenuItem item)método dentro del objeto ActionBarDrawerToggle con esto:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item != null && item.getItemId() == android.R.id.home) {
            if (mDrawer.isDrawerOpen(Gravity.RIGHT)) {
                mDrawer.closeDrawer(Gravity.RIGHT);
            } else {
                mDrawer.openDrawer(Gravity.RIGHT);
            }
            return true;
        }
        return false;
    }

asegúrese de llamar a esto desde onOptionsItemSelected(MenuItem item)la Actividad:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

if(mDrawerToggle.onOptionsItemSelected(item)) {
    return true;
}

return super.onOptionsItemSelected(item);
}

Esto le permitirá utilizar la función del botón de inicio. Para mover el botón al lado derecho de la barra de acción, tendrá que implementar un elemento de acción personalizado y tal vez algunas otras cosas para que funcione como desea.


3

el problema principal con el siguiente error:

no se encontró vista de cajón con gravedad absoluta IZQUIERDA

es que, definiste el

android:layout_gravity="right"

para la vista de lista en la derecha, pero intente abrir el cajón desde la izquierda, llamando a esta función:

mDrawerToggle.syncState();

y haciendo clic en el icono de hamburguesa!

¡solo comente la función anterior e intente manejar abrir / cerrar el menú como dijo @Rudi!


3

He resuelto este problema cambiando la gravedad de la vista de navegación

android: layout_gravity

para terminar en lugar de inicio

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/activity_drawer" />

Funcionó para mí.


2

Primero debe poner este código en su AppManifest.xml en la etiqueta de la aplicación:

android:supportsRtl="true"

luego, en su archivo activity_main.xml, coloque este fragmento de código:

android:layout_direction="rtl"

esa es la mejor solución jamás, me salvas el día gracias
Ahmed Mousa

2

Hice la siguiente modificación al ejemplo de actividad del cajón de navegación en Android Studio. Con bibliotecas de soporte 25.3.1.

MainActivity.java:

private DrawerLayout mDrawerLayout;

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

    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
    }

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
}

@Override
public void onBackPressed() {
    if (mDrawerLayout.isDrawerOpen(GravityCompat.END)) {
        mDrawerLayout.closeDrawer(GravityCompat.END);
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int itemId = item.getItemId();
    switch (itemId) {
        case android.R.id.home:
            finish();
            return true;

        case R.id.action_right_drawer:
            if (mDrawerLayout.isDrawerOpen(GravityCompat.END)) {
                mDrawerLayout.closeDrawer(GravityCompat.END);
            } else {
                mDrawerLayout.openDrawer(GravityCompat.END);
            }
            return true;

        default:
            return super.onOptionsItemSelected(item);
    }
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.

    mDrawerLayout.closeDrawer(GravityCompat.END);
    return true;
}

main.xml (descargue ic_menu_white_24px desde https://material.io/icons/ ):

<?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/action_right_drawer"
        android:title="Drawer menu"
        android:icon="@drawable/ic_menu_white_24px"
        android:orderInCategory="100"
        app:showAsAction="always" />
</menu>

En activity_main.xml cambiar

android:layout_gravity="start"

a

android:layout_gravity="end"

2

Abrirlo desde rtl no es bueno para la experiencia del usuario, para que responda a la configuración regional del usuario, acabo de agregar la siguiente línea a mis parámetros DrawerLayout:

android:layoutDirection="locale"

Lo agregué a mi AppBarLayout para que el diseño de la hamburguesa también coincida con la dirección de apertura del cajón.


1

Propiedades de DrawerLayoutandroid:layout_gravity="right|end" y propiedad tools:openDrawer="end" NavigationViewandroid:layout_gravity="end"

XML Layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:layout_gravity="right|end"
    tools:openDrawer="end">

    <include layout="@layout/content_main" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

Java Code

// Appropriate Click Event or Menu Item Click Event

if (drawerLayout.isDrawerOpen(GravityCompat.END)) 
{
     drawerLayout.closeDrawer(GravityCompat.END);
} 
else 
{
     drawerLayout.openDrawer(GravityCompat.END);
}
//With Toolbar
toolbar = (Toolbar) findViewById(R.id.toolbar);

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.setDrawerListener(toggle);
toggle.syncState();

toolbar.setNavigationOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            //Gravity.END or Gravity.RIGHT
            if (drawer.isDrawerOpen(Gravity.END)) {
                drawer.closeDrawer(Gravity.END);
            } else {
                drawer.openDrawer(Gravity.END);
            }
        }
    });
//...
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.