La barra de herramientas de AppCompat v7 no funciona
Tengo dos fragmentos en una actividad. Cuando aparezca el fragmento A, quiero que el icono de la hamburguesa del cajón de navegación se muestre y el cajón de navegación funcione. Cuando el fragmento B está mostrando, quiero que la flecha hacia atrás muestre y cuando se hace clic en hacer una navegación hacia arriba. Sin embargo, no puedo conseguir la nueva barra de herramientas de AppCompat v7 para mostrar la flecha hacia arriba en todo dentro de mi ActionBarActivity a menos que el cajón de nav esté abierto.
En mi actividad, para mi método onCreate () tengo …
- elemento del menú no se muestra como acción android.support.v7.widget.Toolbar
- Android: layout_height = "? Attr / actionBarSize" no funciona con soporte: design: 23.0.0 'library
- Efecto de ondulación en la barra de herramientas cortada
- ¿Cómo puedo ver mi barra de estado de aplicaciones como Google Maps?
- CoordinatorLayout: Ocultando / Mostrando barra de herramientas medio visible?
toolbar = (Toolbar) findViewById(R.id.toolbar); if (toolbar != null) { setSupportActionBar(toolbar); } mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close); mDrawerLayout.setDrawerListener(mDrawerToggle); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true);
Y entonces llamo mDrawerToggle.syncState();
En mi onPostCreate ()
He intentado buscar en cómo activar programaticamente el icono de la barra de herramientas a la flecha hacia atrás, pero nada ha funcionado. Por lo que he recogido, llamando
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayShowHomeEnabled(true); getSupportActionBar().setHomeButtonEnabled(true);
De mi fragmento debe cambiar el icono, pero ese no es el caso. Esto puede ser una pregunta estúpida, pero ¿qué estoy haciendo mal?
- ¿Cómo hacer transparente la barra de herramientas?
- Cómo cambiar los iconos de los iconos del menú de navegación y desbordamiento de la barra de herramientas (appcompat v7)?
- ActionBarDrawerToggle no se puede aplicar a Android.support.v7.widget.Toolbar
- Barra de herramientas Android demasiado alta en modo horizontal
- Barra de herramientas para fragmentos y Gaveta de navegación
- Android: ¿Cómo / Tutorial para cambiar ActionBar a ActionBarCompat (Barra de herramientas)?
- Android: Estilo ActionMode en AppCompat-v7 con la barra de herramientas
- Cómo personalizar la fuente de subtítulos de la barra de acción?
Por lo que he visto en el código fuente de v7 ActionBarDrawerToggle
, puede animar el icono a diferentes estados sin tener el cajón abierto.
private enum ActionDrawableState{ BURGER, ARROW } private static void toggleActionBarIcon(ActionDrawableState state, final ActionBarDrawerToggle toggle, boolean animate){ if(animate) { float start = state == ActionDrawableState.BURGER ? 0f : 1.0f; float end = Math.abs(start - 1); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { ValueAnimator offsetAnimator = ValueAnimator.ofFloat(start, end); offsetAnimator.setDuration(300); offsetAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); offsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float offset = (Float) animation.getAnimatedValue(); toggle.onDrawerSlide(null, offset); } }); offsetAnimator.start(); }else{ //do the same with nine-old-androids lib :) } }else{ if(state == ActionDrawableState.BURGER){ toggle.onDrawerClosed(null); }else{ toggle.onDrawerOpened(null); } } }
Morphing entre Burger y Arrow depende de valores entre 0f
y 1.0f
, básicamente estos son valores que el cajón pasa al ActionBarDrawerToggle.
Utilicé ValueAnimator
para animar valores en este rango, es decir, imitando el giro del cajón.
null
argumentos null
son seguros porque ActionBarDrawerToggle
no le interesa en absoluto las vistas de los cajones. Asegúrese de echar un vistazo a los nuevos interpoladores para hacer la animación totalmente por el libro de las directrices de diseño de materiales:
fast_out_linear_in fast_out_slow_in
Otra aproximación es acceder al campo privado mSlider
del ActionBarDrawer
través del ActionBarDrawer
reflexión y llamada setPosition(float position)
para alternar entre Burger y Arrow. mSlider
es del tipo (extends) DrawerArrowDrawable
.
Personalmente, siempre trato de evitar la reflexión, siempre y cuando no hay otra manera de hacer su trabajo sucio.
Como la biblioteca de soporte actualizada a 23.0.0, hay una mejor manera de reproducir animación de flecha de cajón. Así que voy a mejorar @ Nikola respuesta. Aquí está el código:
public static void playDrawerToggleAnim(final DrawerArrowDrawable d) { float start = d.getProgress(); float end = Math.abs(start - 1); ValueAnimator offsetAnimator = ValueAnimator.ofFloat(start, end); offsetAnimator.setDuration(300); offsetAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); offsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float offset = (Float) animation.getAnimatedValue(); d.setProgress(offset); } }); offsetAnimator.start(); }
Y llámelo cuando quiera por:
playDrawerToggleAnim((DrawerArrowDrawable) toolbar.getNavigationIcon());
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { int stackHeight = getSupportFragmentManager().getBackStackEntryCount(); if (stackHeight > 0) { // if we have something on the stack (doesn't include the current shown fragment) getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); } else { getSupportActionBar().setDisplayHomeAsUpEnabled(false); getSupportActionBar().setHomeButtonEnabled(false); } } });
Después …
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: getSupportFragmentManager().popBackStack(); return true; .... }
En mi caso el icono está animando: He usado ActionBarDrawerToggle v7.
Actividad principal:
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); } @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(); }