Cómo implementar DrawerArrowToggle desde la biblioteca de Android appcompat v7 21
android-actionbar android-5.0-lollipop (5)
Creé una pequeña aplicación que tenía una funcionalidad similar
Actividad principal
public class MyActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar);
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(
this,
drawerLayout,
toolbar,
R.string.open,
R.string.close
)
{
public void onDrawerClosed(View view)
{
super.onDrawerClosed(view);
invalidateOptionsMenu();
syncState();
}
public void onDrawerOpened(View drawerView)
{
super.onDrawerOpened(drawerView);
invalidateOptionsMenu();
syncState();
}
};
drawerLayout.setDrawerListener(actionBarDrawerToggle);
//Set the custom toolbar
if (toolbar != null){
setSupportActionBar(toolbar);
}
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
actionBarDrawerToggle.syncState();
}
}
Mi XML de esa actividad
<android.support.v4.widget.DrawerLayout 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"
tools:context=".MyActivity"
android:id="@+id/drawer"
>
<!-- The main content view -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<include layout="@layout/toolbar_custom"/>
</FrameLayout>
<!-- The navigation drawer -->
<ListView
android:layout_marginTop="?attr/actionBarSize"
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="#457C50"/>
</android.support.v4.widget.DrawerLayout>
Mi barra de herramientas personalizada XML
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/toolbar"
android:background="?attr/colorPrimaryDark">
<TextView android:text="U titel"
android:textAppearance="@android:style/TextAppearance.Theme"
android:textColor="@android:color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</android.support.v7.widget.Toolbar>
Mi estilo de tema
<resources>
<style name="AppTheme" parent="Base.Theme.AppCompat"/>
<style name="AppTheme.Base" parent="Theme.AppCompat">
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primaryDarker</item>
<item name="android:windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">@android:color/white</item>
</style>
<color name="primary">#457C50</color>
<color name="primaryDarker">#580C0C</color>
</resources>
Mis estilos en valores-v21
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>
</style>
</resources>
Entonces, ahora que se lanzó Android 5.0, me preguntaba cómo implementar los íconos animados de la barra de acción.
Esta biblioteca here implementa bien para mí, pero dado que la biblioteca appcompat v7 la tiene, ¿cómo se puede implementar?
La biblioteca lo hace referencia en themes.xml
<item name="drawerArrowStyle">@style/Widget.AppCompat.DrawerArrowToggle</item>
Bajo este estilo
<style name="Base.V7.Theme.AppCompat" parent="Platform.AppCompat">
ACTUALIZAR
Lo implementé usando v7 DrawerToggle. Sin embargo, no puedo diseñarlo. Por favor ayuda
Encontré el estilo en v7 styles_base.xml
<style name="Base.Widget.AppCompat.DrawerArrowToggle" parent="">
<item name="color">?android:attr/textColorSecondary</item>
<item name="thickness">2dp</item>
<item name="barSize">18dp</item>
<item name="gapBetweenBars">3dp</item>
<item name="topBottomBarArrowSize">11.31dp</item>
<item name="middleBarArrowSize">16dp</item>
<item name="drawableSize">24dp</item>
<item name="spinBars">true</item>
</style>
Agregué esto a mis estilos y no funcionó. También agregado a mi attr.xml
<declare-styleable name="DrawerArrowToggle">
<!-- The drawing color for the bars -->
<attr name="color" format="color"/>
<!-- Whether bars should rotate or not during transition -->
<attr name="spinBars" format="boolean"/>
<!-- The total size of the drawable -->
<attr name="drawableSize" format="dimension"/>
<!-- The max gap between the bars when they are parallel to each other -->
<attr name="gapBetweenBars" format="dimension"/>
<!-- The size of the top and bottom bars when they merge to the middle bar to form an arrow -->
<attr name="topBottomBarArrowSize" format="dimension"/>
<!-- The size of the middle bar when top and bottom bars merge into middle bar to form an arrow -->
<attr name="middleBarArrowSize" format="dimension"/>
<!-- The size of the bars when they are parallel to each other -->
<attr name="barSize" format="dimension"/>
<!-- The thickness (stroke size) for the bar paint -->
<attr name="thickness" format="dimension"/>
</declare-styleable>
Pero se bloquea y dice error de tipo de color al hacerlo. ¿Qué me estoy perdiendo?
Para responder la parte actualizada de su pregunta: para diseñar el ícono / flecha del cajón, tiene dos opciones:
Dale estilo a la flecha
Para hacer esto, anule
drawerArrowStyle
en su tema de la siguiente manera:
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
<item name="drawerArrowStyle">@style/MyTheme.DrawerArrowToggle</item>
</style>
<style name="MyTheme.DrawerArrowToggle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="color">@android:color/holo_purple</item>
<!-- ^ this will make the icon purple -->
</style>
Probablemente esto no sea lo que desea , porque la barra de acción en sí misma debe tener un estilo consistente con la flecha, por lo que, lo más probable es que desee la opción dos:
Tema de la barra de herramientas / barra de herramientas
Anule el atributo
android:actionBarTheme
(
actionBarTheme
for appcompat) del tema de aplicación global con su propio tema (que probablemente debería derivar de
ThemeOverlay.Material.ActionBar/ThemeOverlay.AppCompat.ActionBar
) de esta manera:
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
<item name="actionBarTheme">@style/MyTheme.ActionBar</item>
</style>
<style name="MyTheme.ActionBar" parent="ThemeOverlay.AppCompat.ActionBar">
<item name="android:textColorPrimary">@android:color/white</item>
<!-- ^ this will make text and arrow white -->
<!-- you can also override drawerArrowStyle here -->
</style>
Una nota importante aquí es que cuando se usa un diseño personalizado con una
Toolbar
de
Toolbar
lugar de la implementación de la
Toolbar
de
Toolbar
de acción (por ejemplo, si está usando el
DrawerLayout
-
NavigationView
-
Toolbar
para lograr el efecto de cajón estilo Material donde es visible bajo la barra de estado translúcida), el
actionBarTheme
atributo actionBarTheme no se recoge automáticamente (porque
AppCompatActivity
en
AppCompatActivity
para la
ActionBar
predeterminada), por lo que para su
Toolbar
personalizada no olvide aplicar su tema manualmente:
<!--inside your custom layout with DrawerLayout
and NavigationView or whatever -->
<android.support.v7.widget.Toolbar
...
app:theme="?actionBarTheme">
- esto se resolverá en el ThemeOverlay.AppCompat.ActionBar predeterminado de
ThemeOverlay.AppCompat.ActionBar
o su anulación si establece el atributo en su tema derivado.
PD:
un pequeño comentario sobre la anulación
drawerArrowStyle
y el atributo
spinBars
, que muchas fuentes sugieren que debería establecerse en
true
para obtener la animación del cajón / flecha.
La cosa es que
spinBars
es
true
de manera predeterminada
en AppCompat (consulte el estilo
Base.Widget.AppCompat.DrawerArrowToggle.Common
), no tiene que anular
actionBarTheme
para que la animación funcione.
Obtiene la animación incluso si la anula y establece el atributo en
false
, es solo una animación diferente y menos retorcida.
Lo importante aquí es usar
ActionBarDrawerToggle
, es lo que atrae al elegante dibujo animado.
Primero, debe saber ahora que
android.support.v4.app.ActionBarDrawerToggle
está en desuso.
Debe reemplazar eso con
android.support.v7.app.ActionBarDrawerToggle
.
Aquí está mi ejemplo y uso la nueva
Toolbar
de
Toolbar
para reemplazar la
Toolbar
de
ActionBar
.
MainActivity.java
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(
this, mDrawerLayout, mToolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close
);
mDrawerLayout.setDrawerListener(mDrawerToggle);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
mDrawerToggle.syncState();
}
styles.xml
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">@android:color/white</item>
</style>
Puede leer los documentos en AndroidDocument#DrawerArrowToggle_spinBars
Este atributo es la clave para implementar la animación de menú a flecha.
public static int DrawerArrowToggle_spinBars
Si las barras deben rotar o no durante la transición
Debe ser un valor booleano, "verdadero" o "falso".
Entonces, configura esto:
<item name="spinBars">true</item>
.
Luego se puede presentar la animación.
Espero que esto le pueda ayudar.
Quiero corregir un poco el código anterior
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(
this, mDrawerLayout, mToolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close
);
mDrawerLayout.setDrawerListener(mDrawerToggle);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
y todas las demás cosas permanecerán igual ...
Para aquellos que tienen problemas
Drawerlayout
barra de herramientas de superposición de
Drawerlayout
agregue
android:layout_marginTop="?attr/actionBarSize"
al diseño raíz del contenido del cajón
Si está utilizando el DrawerLayout proporcionado por la Biblioteca de soporte, tal como se sugiere en la capacitación Creación de un cajón de navegación , puede usar el nuevo android.support agregado . v7 .app.ActionBarDrawerToggle (nota: diferente del ahora obsoleto android.support. v4 .app.ActionBarDrawerToggle ):
muestra un icono de hamburguesa cuando el cajón está cerrado y una flecha cuando el cajón está abierto. Se anima entre estos dos estados cuando se abre el cajón.
Si bien la capacitación no se ha actualizado para tener en cuenta la depreciación / nueva clase, debería poder usarla casi exactamente con el mismo código; la única diferencia en la implementación es el constructor.