usar - navigation drawer material design android
Al hacer clic en el icono de hamburguesa en la barra de herramientas no se abre el cajón de navegación (9)
Tengo un simple android.support.v7.widget.Toolbar
y todo lo que estoy tratando de hacer es abrir un NavigationDrawer presionando el ícono "hamburguesa" en la esquina superior izquierda. El botón "hamburguesa" está visible, y cuando comienzo a tirar desde la izquierda, veo la animación en el botón, pero al presionar el botón no se abre / cierra el NavigationDrawer como esperaba. He seguido la [Documentación de Google] [1] y todavía no puedo resolver esto. Lo siento por cualquier confusión, a continuación se muestra el código simplificado que estoy intentando usar actualmente:
public class MainActivity extends AppCompatActivity implements
View.OnClickListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("NICK", "button button button..................");
}
});
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
NavigationView n = (NavigationView) findViewById(R.id.nav);
mDrawerLayout.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
Log.d("NICK", "button button button..................");
}
});
//mDrawerLayout.setDrawerListener(mDrawerToggle);
n.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
////.......
}
mDrawerLayout.closeDrawers(); // CLOSE DRAWER
return true;
}
});
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d("NICK","CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
switch (item.getItemId()) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START); // OPEN DRAWER
Log.d("NICK","CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.drawer, menu);
return true;
}
}
}
Y como es, no obtengo ninguna de las sentencias de depuración del registro cuando se ejecuta.
Este es esencialmente el problema que tengo: https://stackoverflow.com/a/26636045/1489990 . He seguido esto y simplemente no funciona.
Entiendo que se llama a setNavigationOnClickListener
cuando se presiona el ícono de la hamburguesa, y aquí es donde estoy enfocando mis esfuerzos para que el evento se maneje adecuadamente porque cuando presiono el botón no obtengo mi declaración de registro. Déjame saber si esta idea es incorrecta. https://developer.android.com/reference/android/widget/Toolbar.html#setNavigationOnClickListener(android.view.View.OnClickListener)
Mis diseños:
ActivityMain.xml
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/d"
android:background="@drawable/home_wall">
<android.support.v7.widget.Toolbar
android:id="@+id/my_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:layout_marginBottom="10dp"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:layout_marginTop="25dp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" />
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:id="@+id/drawer"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ImageView
android:layout_width="fill_parent"
android:layout_height="200dp"
android:id="@+id/imageView"
android:src="@drawable/trans2"
android:layout_alignParentTop="true"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:paddingBottom="300dp" />
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/d8"
android:layout_alignParentTop="true"
android:layout_alignLeft="@+id/imageView"
android:layout_alignStart="@+id/imageView"
android:paddingTop="0dp">
<Button
android:layout_width="75dp"
android:layout_height="50dp"
android:text="Gallery"
android:id="@+id/save_button"
android:background="#dd2c00" android:textColor="#fff"
android:layout_below="@+id/Purchases"
android:layout_toRightOf="@+id/start_button"
android:layout_toEndOf="@+id/start_button" />
<Button
android:layout_width="125dp"
android:layout_height="50dp"
android:text="Store"
android:id="@+id/Purchases"
android:background="#ff6e40" android:textColor="#fff"
android:layout_above="@+id/instructions_button6"
android:layout_toLeftOf="@+id/start_button"
android:layout_toStartOf="@+id/start_button"
android:layout_marginBottom="98dp" />
<Button
android:layout_width="75dp"
android:layout_height="50dp"
android:text="Help"
android:id="@+id/instructions_button6"
android:background="#dd2c00" android:textColor="#fff"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@+id/start_button"
android:layout_toStartOf="@+id/start_button"
android:layout_marginLeft="5dp"
android:layout_marginBottom="10dp" />
<Button
android:layout_width="75dp"
android:layout_height="300dp"
android:text="Start"
android:id="@+id/start_button"
android:background="#ff3d00"
android:textColor="#fff"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp" />
<Button
android:layout_width="125dp"
android:layout_height="50dp"
android:text="Achievements"
android:id="@+id/Scores"
android:background="#ff6e40" android:textColor="#fff"
android:layout_alignTop="@+id/Purchases"
android:layout_toRightOf="@+id/start_button"
android:layout_toEndOf="@+id/start_button" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome to the quiz!"
android:id="@+id/textView"
android:textColor="#fff"
android:textSize="20dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="70dp" />
<!-- sign-in button -->
<com.google.android.gms.common.SignInButton
android:id="@+id/sign_in_button"
android:layout_width="110dp"
android:layout_height="50dp"
android:layout_above="@+id/start_button"
android:layout_centerHorizontal="true"
android:visibility="visible" />
<!-- sign-out button -->
<Button
android:id="@+id/sign_out_button"
android:layout_width="125dp"
android:layout_height="wrap_content"
android:text="Sign Out"
android:visibility="invisible"
android:background="#dd4b39"
android:textColor="#fff"
android:layout_alignTop="@+id/sign_in_button"
android:layout_centerHorizontal="true"
android:layout_marginTop="160dp" />
</RelativeLayout>
<android.support.design.widget.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#fff"
android:id="@+id/nav"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
Drawer.xml
:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_menu"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:title="Google Play Games"
android:icon="@drawable/ic_local_airport_white_48dp">
<menu>
<item
android:id="@+id/Sign_in_drawer"
android:icon="@drawable/games_controller_grey"
android:title="Sign in" />
<item
android:id="@+id/ach"
android:icon="@drawable/games_achievements"
android:title="Achievements" />
</menu>
</item>
<item android:title="Start a Quiz"
android:icon="@drawable/ic_local_airport_white_48dp">
<menu>
<item
android:id="@+id/quizStart25"
android:icon="@drawable/ic_local_airport_white_48dp"
android:title="25 Questions" />
<item
android:id="@+id/quizStart10"
android:icon="@drawable/ic_local_airport_white_48dp"
android:title="10 Questions" />
</menu>
</item>
<group
android:checkableBehavior="single">
<item
android:id="@+id/gallery"
android:icon="@drawable/ic_photo_library_white_48dp"
android:title="Gallery" />
<item
android:id="@+id/stats"
android:icon="@drawable/ic_toc_white_48dp"
android:title="Statistics" />
<item
android:id="@+id/store"
android:icon="@drawable/ic_shop_white_48dp"
android:title="Store" />
<item
android:id="@+id/settings"
android:icon="@drawable/ic_settings_white_48dp"
android:title="Settings" />
<item
android:id="@+id/about"
android:icon="@drawable/ic_info_white_48dp"
android:title="About" />
</group>
<item android:title="Support">
<menu>
<item
android:id="@+id/help_drawer"
android:icon="@drawable/ic_help_white_48dp"
android:title="Help" />
<item
android:id="@+id/report"
android:icon="@drawable/ic_report_problem_white_48dp"
android:title="Contact Developer" />
<item
android:id="@+id/GPlusCommunity"
android:icon="@drawable/btn_g_white_normal"
android:title="Google+ Community" />
</menu>
</item>
Aunque la respuesta aceptada aquí funciona bien, sin embargo, como dicen "más vale prevenir que curar". Agregar mDrawerToggle.syncState (); en onPostCreate y onConfigurationChanged () funciona mucho mejor como se responde por @mbmc arriba:
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
Como no tengo una respuesta específica a su problema, quiero sugerir un enfoque completamente diferente:
En mis proyectos estoy usando el Material Drawer desarrollado por Mike Penz. Se ve realmente bien, es fácil de implementar y no hay mucho de lo que deba preocuparse.
Entonces, si no puede encontrar una solución a su problema, puede intentarlo.
Necesitas sincronizar la palanca del cajón:
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
EDITAR: ese código está funcionando para mí (copiado de su publicación)
public class TempActivity extends AppCompatActivity {
private ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.temp);
setupDrawer();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
private void setupDrawer() {
Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.my_drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,toolbar,R.string.drawer_open, R.string.drawer_close) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
}
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/my_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<RelativeLayout
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#111">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFF"
android:text="DRAMER MENU" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
Pero si está utilizando el nuevo NavigationView
, entonces no necesita el interruptor, etc. Aquí hay un buen ejemplo de cómo usarlo.
Para el conmutador del cajón, debe configurar "mostrar inicio como arriba" en falso: getSupportActionBar().setDisplayHomeAsUpEnabled(false);
Si ayuda a alguien, a mí me pasó lo mismo debido al error estúpido de llamar a setSupportActionBar(toolbar)
dos veces. Solo llámelo una vez en el método onCreate y nunca más. Mi error fue que lo llamé más tarde en otro método.
Simplemente llame a la función onOptionsItemSelected (MenuItem menuItem) de la clase ActionBarDrawerToggle en la función de administración del menú de opciones de actividad como se muestra a continuación.
mDrawerToggle= new ActionBarDrawerToggle(activity, drawerLayout, R.string.nav_drawer_accessbility_drawer_open,
R.string.nav_drawer_accessbility_drawer_close);
@Override
public boolean onOptionsItemSelected(final android.view.MenuItem item) {
navigation().getOptionsMenuInflater(this).closeSearchView();
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this behavior.
mDrawerToggle.onOptionsItemSelected(item);
return super.onOptionsItemSelected(item);
}
O
anular onOptionsItemSeleccionado de actividad como a continuación
public boolean onOptionsItemSelected(MenuItem item) {
if (item != null && item.getItemId() == android.R.id.home) {
toggle();
}
return super.onOptionsItemSelected(item);
}
private void toggle() {
if (mDrawerLayout.isDrawerVisible(GravityCompat.START)) {
mDrawerLayout.closeDrawer(GravityCompat.START);
} else {
mDrawerLayout.openDrawer(GravityCompat.START);
}
}
Usa ActionBarDrawerToggle
e implementa public boolean onOptionsItemSelected(MenuItem item)
La barra de herramientas NO tiene que estar dentro de DrawerLayout, no es probable que sea la causa de este problema. toggle.onOptionsItemSelected(item)
busca el ID del elemento seleccionado y, si se trata de android.R.id.home
, la visibilidad del cajón cambia. Por lo tanto, la barra de herramientas, o cualquier vista que cree un elemento de menú de inicio, se puede colocar en cualquier lugar de su diseño.
Dentro de su actividad:
ActionBarDrawerToggle toggle;
private void setupDrawerToggleInActionBar() {
// assuming a Toolbar has been initialized in your onCreate
this.setSupportActionBar(toolbar);
// setup the action bar properties that give us a hamburger menu
ActionBar actionBar = this.getSupportActionBar();
if(actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
}
// the toggle allows for the simplest of open/close handling
toggle = new ActionBarDrawerToggle(this,
drawerLayout,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
// drawerListener must be set before syncState is called
drawerLayout.setDrawerListener(toggle);
toggle.setDrawerIndicatorEnabled(true);
toggle.syncState();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// This is required to make the drawer toggle work
if(toggle.onOptionsItemSelected(item)) {
return true;
}
/*
* if you have other menu items in your activity/toolbar
* handle them here and return true
*/
return super.onOptionsItemSelected(item);
}
Ver mi answer a una publicación similar.
Básicamente, solo omita el ActionBarDrawerToggle
si no lo necesita para otras cosas (como devoluciones de llamada). Puede eliminar todo ese código y simplemente implementar el comportamiento de abrir / cerrar el cajón, de esta manera:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START); // OPEN DRAWER
return true;
....
}
return super.onOptionsItemSelected(item);
}
El segmento de código anterior funciona independientemente de si está utilizando NavigationView . Si está utilizando la vista de navegación, en su detector de clics de NavigationView:
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// Handle menu item clicks here.
drawerLayout.closeDrawers(); // CLOSE DRAWER
return true;
}
});
Actualizar:
Además, asegúrese de que su actividad esté extendiendo AppCompatActivity
(y no ActionBarActivity
). Vea mi respuesta aquí para más información.
Actualización2:
He depurado tu código revisado. Prueba esto. Debería funcionar ahora. Lee mis comentarios en línea para ver qué he cambiado y por qué:
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
// View.OnClickListener,
// GoogleApiClient.ConnectionCallbacks,
// GoogleApiClient.OnConnectionFailedListener {
DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
// You were missing this setHomeAsUpIndicator
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// I removed your toolbar and drawer click listeners.
// They''re not needed to open drawer.
// The drawer opens from onOptionsItemSelected().
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
NavigationView n = (NavigationView) findViewById(R.id.nav);
n.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
////.......
}
mDrawerLayout.closeDrawers(); // CLOSE DRAWER
return true;
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d("NICK", "CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
switch (item.getItemId()) {
// THIS IS YOUR DRAWER/HAMBURGER BUTTON
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START); // OPEN DRAWER
Log.d("NICK", "CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
return true;
}
return super.onOptionsItemSelected(item);
}
}
// I also removed your onConfigurationChanged().
// It''s not needed since you''re no longer using ActionBarDrawerToggle.
Update3: EL PROBLEMA ES CON EL DISEÑO
Mirando su ActivityMain.xml, veo que su barra de herramientas está fuera de su DrawerLayout. No puedes hacer eso. La barra de herramientas debe ser hija de DrawerLayout para que la barra de herramientas encuentre el contexto adecuado.
Necesitas que DrawerLayout sea la raíz de tu actividad. Aquí está la documentation , y la cita específica es:
Para agregar un cajón de navegación, declare su interfaz de usuario con un objeto DrawerLayout como la vista raíz de su diseño. Dentro del DrawerLayout, agregue una vista que contenga el contenido principal de la pantalla (su diseño principal cuando el cajón esté oculto) y otra vista que contenga el contenido del cajón de navegación.
Básicamente, cambie su ActivityMain.xml para verse así:
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer"
... >
<RelativeLayout
android:id="@+id/d"
...>
<android.support.v7.widget.Toolbar
android:id="@+id/my_toolbar"
... />
<!-- Your other content goes here -->
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="@+id/nav"
... />
</android.support.v4.widget.DrawerLayout>
Con suerte, eso se encarga de tus problemas.
onOptionsItemSelected
método onOptionsItemSelected
y use a continuación
if(item.getItemId() == android.R.id.home){ // use android.R.id
mDrawerLayout.openDrawer(Gravity.LEFT);
}