web-dev-qa-db-fra.com

Comment implémenter DrawerArrowToggle à partir de la bibliothèque Android appcompat v7 21

Alors maintenant que Android 5.0 est sorti, je me demandais comment implémenter les icônes de la barre d’action animée.

Cette bibliothèque ici l'implémente bien pour moi, mais depuis la bibliothèque appcompat v7, comment peut-elle être implémentée?

La bibliothèque le référence dans themes.xml

 <item name="drawerArrowStyle">@style/Widget.AppCompat.DrawerArrowToggle</item>

Sous ce style

 <style name="Base.V7.Theme.AppCompat" parent="Platform.AppCompat">

MISE À JOUR

Cela a été implémenté à l’aide de la v7 DrawerToggle. Cependant, je ne peux pas le nommer. S'il vous plaît aider

J'ai trouvé le style pour cela dans la 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>

J'ai ajouté ceci à mes styles et je n'ai pas fonctionné. Également ajouté à mon 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>

Mais se bloque et dit une erreur de type de couleur en le faisant. Qu'est-ce que je rate?

96
Bignadad

Tout d’abord, vous devez savoir maintenant que le Android.support.v4.app.ActionBarDrawerToggle est obsolète.

Vous devez remplacer cela par Android.support.v7.app.ActionBarDrawerToggle.

Voici mon exemple et j'utilise le nouveau Toolbar pour remplacer le 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>

Vous pouvez lire les documents sur AndroidDocument # DrawerArrowToggle_spinBars

Cet attribut est la clé pour implémenter l'animation menu-à-flèche.

public int int DrawerArrowToggle_spinBars

Indique si les barres doivent pivoter ou non pendant la transition
Doit être une valeur booléenne, "true" ou "false".

Donc, vous définissez ceci: <item name="spinBars">true</item>.

Ensuite, l'animation peut être présentée.

J'espère que cela peut vous aider.

242
Yong

Si vous utilisez la bibliothèque de support fournie DrawerLayout comme suggéré dans le Création d’une formation sur le tiroir de navigation , vous pouvez utiliser le nouveau Android.support). v7 . app.ActionBarDrawerToggle (note: différent de l'actuel obsolète Android.support. v4 . app.ActionBarDrawerToggle ):

affiche une icône Hamburger lorsque le tiroir est fermé et une flèche lorsque le tiroir est ouvert. Il s'anime entre ces deux états lorsque le tiroir s'ouvre.

Bien que la formation n'ait pas été mise à jour pour prendre en compte la classe obsolète/nouvelle classe, vous devriez pouvoir l'utiliser presque exactement avec le même code. La seule différence dans son implémentation est le constructeur.

24
ianhanniballake

J'ai créé une petite application qui avait des fonctionnalités similaires

Activité principale

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();
    }
}

Mon XML de cette activité

<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>

Mon XML personnalisé de barre d'outils

<?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>

Mon style de thème

<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>

Mes styles dans values-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>
17
tim

Pour répondre à la partie mise à jour de votre question: pour styler l’icône/flèche du tiroir, vous avez deux options:

Style de la flèche elle-même

Pour ce faire, remplacez drawerArrowStyle dans votre thème de la manière suivante:

<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>

Ce n'est probablement pas ce que vous voulez, car la barre d'action elle-même devrait avoir un style cohérent avec la flèche. Vous souhaiterez donc probablement l'option deux:

Thème la barre d'action/barre d'outils

Remplacez l'attribut Android:actionBarTheme (_ (actionBarTheme pour appcompat) du thème d'application global par votre propre thème (que vous devriez probablement dériver de ThemeOverlay.Material.ActionBar/ThemeOverlay.AppCompat.ActionBar) comme suit:

<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>

Il est important de noter que lorsque vous utilisez une disposition personnalisée avec un Toolbar au lieu d’une implémentation ActionBar standard (par exemple, si vous utilisez le combo DrawerLayout-NavigationView-Toolbar Pour obtenir l’effet de tiroir Matériau où il est visible dans la barre d’état translucide), l’attribut actionBarTheme n’est pas détecté automatiquement (car il est censé être pris en charge par AppCompatActivity pour le paramètre par défaut ActionBar), donc pour votre personnalisation Toolbar n'oubliez pas d'appliquer votre thème manuellement:

<!--inside your custom layout with DrawerLayout
and NavigationView or whatever -->
<Android.support.v7.widget.Toolbar
        ...
        app:theme="?actionBarTheme">

- cela résoudra soit par défaut ThemeOverlay.AppCompat.ActionBar par défaut d'AppCompat, soit votre remplacement si vous définissez l'attribut dans votre thème dérivé.

PS un petit commentaire sur le drawerArrowStyle override et l'attribut spinBars - que beaucoup de sources suggèrent d'être régler sur true pour obtenir l’animation tiroir/flèche. La chose est, spinBars c'est truepar défaut dans AppCompat (consultez le style Base.Widget.AppCompat.DrawerArrowToggle.Common), vous n'avez pas à remplacer actionBarTheme du tout pour que l'animation fonctionne. Vous obtenez l'animation même si vous la remplacez et que vous définissez l'attribut sur false, il s'agit simplement d'une animation différente, moins dynamique. La chose importante ici est d’utiliser ActionBarDrawerToggle, c’est ce qui attire les dessins animés fantaisistes.

9
Ivan Bartsov

Je veux corriger un peu le code ci-dessus

    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);
    }

et toutes les autres choses resteront les mêmes ...

Pour ceux qui ont des problèmes Drawerlayout superposer la barre d'outils

ajoute Android:layout_marginTop="?attr/actionBarSize" à la disposition racine du contenu du tiroir

2
Nitin Misra