android - ejemplo - navigation drawer material design
Barra de herramientas de soporte de Android+ActionBarDrawerToggle no cambia a flecha (5)
Creo que todo lo que tienes que hacer es eliminar el tercer argumento. Así:
mDrawerToggle = new ActionBarDrawerToggle(
getActivityCompat(), /* host Activity */
mDrawerLayout, /* DrawerLayout object */
// ((BaseActivity) getActivityCompat()).getToolbar(), <== delete this argument
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
R.string.navigation_drawer_close /* "close drawer" description for accessibility */
);
Que ayude.
Estoy luchando con la barra de herramientas y el cajón. Estoy tratando de hacer que la hamburguesa cambie a flecha cuando estoy agregando un nuevo fragmento al backstack pero no hay forma de hacerlo.
Tal vez me esté perdiendo algo pero no pude encontrar una manera. ¿Alguien tuvo el mismo problema?
Esta es la declaración:
mDrawerToggle = new ActionBarDrawerToggle(
getActivityCompat(), /* host Activity */
mDrawerLayout, /* DrawerLayout object */
((BaseActivity) getActivityCompat()).getToolbar(),
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
R.string.navigation_drawer_close /* "close drawer" description for accessibility */
)
Esta es la función a la que llamo cuando se agrega un fragmento a la pila trasera
public void setToggleState(boolean isEnabled) {
if (mDrawerLayout == null)
return;
if (isEnabled) {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED);
} else {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
mDrawerToggle.syncState();
}
La respuesta de @ hata es acertada para la mayoría de los casos.
Pero en realidad, no estaba equivocado al usar la barra de herramientas como argumento para el ActionBarDrawerToggle(...)
.
Por supuesto, no tiene sentido hacer eso si está usando la Toolbar
AppCompatActivity
proporciona AppCompatActivity
utilizando, por ejemplo, el tema raíz raíz de Theme.AppCompat.Light
. Incluso si desea una Toolbar
de Toolbar
personalizada en su diseño, por ejemplo, si está implementando el patrón del cajón de navegación sobre la barra de herramientas en la barra de estado de Material Design, aún puede llamar a setSupportActionBar(toolbar)
y aún no pasar la barra de herramientas a ActionBarDrawerToggle()
La actividad maneja el icono de navegación.
Pero si realmente desea vincular su ActionBarDrawerToggle
a una Toolbar
que no sea la barra de acción de la actividad, y tal vez tenga un estilo diferente y un ícono diferente o lo que sea, todavía hay mucho camino por recorrer.
El problema es que cuando no se pasa la barra de herramientas como el cuarto parámetro, se supone que la actividad debe proporcionar el ícono de navegación (la flecha), y AppCompatActivity
devuelve el valor del atributo homeAsUpIndicator
, se define en cualquiera de los AppCompat estándar. temas
Sin embargo, cuando pasa explícitamente la Toolbar
, ActionBarDrawerToggle
espera que la instancia de la barra de herramientas proporcione el indicador de navegación que se puede dibujar, y no lo hace, porque incluso si le aplica el estilo apropiado de esta manera:
<android.support.v7.widget.Toolbar
...
app:theme="?actionBarTheme"
style="@style/Widget.AppCompat.Toolbar">
por alguna razón (tal vez incluso sea un error), el estilo Widget.AppCompat.Toolbar
no tiene el atributo de navigationIcon
Widget.AppCompat.Toolbar
, por lo que la Toolbar
devuelve null
cuando ActionBarDrawerToggle
le pide el icono de navegación. Entonces, para hacer frente a esto, simplemente derive del estilo y agregue el atributo:
<android.support.v7.widget.Toolbar
...
app:theme="?actionBarTheme"
style="@style/MyWidget.Toolbar">
<!-- styles.xml -->
<style name="MyWidget.Toolbar" parent="Widget.AppCompat.Toolbar">
<item name="navigationIcon">?homeAsUpIndicator</item>
</style>
Ahora puede usar el constructor ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, 0, 0)
la barra de herramientas ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, 0, 0)
y aún tener el ícono de navegación en su lugar.
Lo he logrado utilizando el siguiente diseño: he usado ActionBarDrawerToggle v7 Drawer.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.toolbar.Drawer" >
<include
android:id="@+id/tool1"
layout="@layout/toolbar" />
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/tool1" >
<FrameLayout
android:id="@+id/mainContent"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<!-- Nav drawer -->
<ListView
android:id="@+id/drawerList"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="@android:color/white"
android:divider="@android:color/white"
android:dividerHeight="8dp"
android:drawSelectorOnTop="true"
android:headerDividersEnabled="true" />
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
toolbar.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app1="http://schemas.android.com/apk/res/com.example.toolbar"
android:id="@+id/my_awesome_toolbar"
android:layout_width="fill_parent"
android:layout_height="75dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app1:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app1:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" >
</android.support.v7.widget.Toolbar>
Drawer.java
paquete com.example.toolbar;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class Drawer extends ActionBarActivity {
ActionBarDrawerToggle mDrawerToggle;
private String[] days;
ArrayAdapter<String> adapter;
private ListView mDrawerList;
DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawer);
days = new String[] { "sunday", "monday", "tuesday", "wednesday",
"thursday", "friday", "saturday" };
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, days);
mDrawerList = (ListView) findViewById(R.id.drawerList);
mDrawerList.setAdapter(adapter);
mDrawerList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
Fragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putString(MyFragment.ARG_PLANET_NUMBER, days[position]);
// args.putInt(MyFragment.ARG_PLANET_NUMBER, position);
fragment.setArguments(args);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.mainContent, fragment).commit();
}
});
Toolbar toolbar = (Toolbar) findViewById(R.id.tool1);
setSupportActionBar(toolbar);
toolbar.setTitle("ToolBar Demo");
toolbar.setLogo(R.drawable.ic_launcher);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar,
R.string.open_navigation_drawer,
R.string.close_navigation_drawer) {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// TODO Auto-generated method stub
super.onDrawerSlide(drawerView, slideOffset);
}
/** Called when a drawer has settled in a completely closed state. */
@Override
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getSupportActionBar().setTitle("hello");
}
/** Called when a drawer has settled in a completely open state. */
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getSupportActionBar().setTitle("hi");
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
// getSupportActionBar().setDisplayHomeAsUpEnabled(true); //<---- added
// getSupportActionBar().setHomeButtonEnabled(true); //<---- added
}
@Override
public boolean onOptionsItemSelected(MenuItem item) { // <---- added
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) { // <---- added
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState(); // important statetment for drawer to
// identify
// its state
}
@Override
public void onConfigurationChanged(Configuration newConfig) { // <---- added
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public void onBackPressed() {
if (mDrawerLayout.isDrawerOpen(Gravity.START | Gravity.LEFT)) { // <----
// added
mDrawerLayout.closeDrawers();
return;
}
super.onBackPressed();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Yo tuve el mismo problema. Mi solución fue la siguiente:
Asegúrese de que su actividad implemente onBackStackChangedListener. En tus actividades onCreate, configuro la escucha de backstack y configuro la barra de herramientas.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFm = getFragmentManager();
mFm.addOnBackStackChangedListener(this);
// Setup toolbar
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.setVisibility(View.VISIBLE);
setSupportActionBar(mToolbar);
// Setup drawer toggle
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.menu_open, R.string.menu_close);
mDrawerLayout.setDrawerListener(mDrawerToggle);
getSupportActionBar().setHomeButtonEnabled(true);
mDrawerToggle.syncState();
// Setup initial fragment
if (savedInstanceState == null) {
mCurrentFragment = DashboardFragment.newInstance();
mFm.beginTransaction().add(CONTAINER_ID, mCurrentFragment).commit();
}
}
También recuerda poner:
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
Ahora la magia sucede en onBackStackChanged (). Al establecer setDrawerIndicatorEnabled en true para el fragmento más alto y setDisplayHomeAsUpEnabled como false para ese fragmento. Inverso para los demás. También tuve que llamar a syncState o la hamburguesa no volvería a aparecer:
@Override
public void onBackStackChanged() {
mDrawerToggle.setDrawerIndicatorEnabled(mFm.getBackStackEntryCount() == 0);
getSupportActionBar().setDisplayHomeAsUpEnabled(mFm.getBackStackEntryCount() > 0);
mDrawerToggle.syncState();
}
esta línea asegura que el ícono de la hamburguesa se cambie a la flecha al hacer clic. Asegúrese de tener esto escrito en su código.
mDrawerLayout.setDrawerListener(mDrawerToggle);