android android-actionbar android-5.0-lollipop appcompat android-appcompat drawertoggle

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.