web-dev-qa-db-fra.com

Comment ajouter l'indicateur "menu" à côté de l'icône de l'application de la barre d'action?

Au moins Gmail et Youtube Android utilisent un menu latéral ( tiroir de navigation ?) Qui s'ouvre en glissant ou en cliquant sur l'icône de l'application (bouton d'accueil):

enter image description here

L'indicateur/l'icône de menu dans la capture d'écran ci-dessus est-il une partie prête à l'emploi de Android SDK? (Ou une icône personnalisée que Google utilise dans ses applications?) Dans tous les cas, quel est le moyen le plus simple pour que votre bouton d'accueil ressemble à ça , c'est-à-dire qu'il ouvre un menu?

(targetSdkVersion 18; minSdkVersion 14)

Résolution

Enfin ça a fonctionné . Ce qui me manquait était 1) l'icône réelle et 2) appel différé à syncState() sur le ActionBarDrawerToggle.

24
Jonik

Pour créer une implémentation/apparence similaire dans votre application, vous devez utiliser ActionBarDrawerToggle et définir votre icône personnalisée comme indicateur à côté du bouton d'accueil ActionBar. Par exemple :

import Android.app.ActionBar;
import Android.support.v4.app.ActionBarDrawerToggle;
import Android.support.v4.widget.DrawerLayout;

private void setUpDrawerToggle(){
    ActionBar actionBar = getActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setHomeButtonEnabled(true);

    // ActionBarDrawerToggle ties together the the proper interactions
    // between the navigation drawer and the action bar app icon.
    mDrawerToggle = new ActionBarDrawerToggle(
            this,                             /* Host Activity */
            mDrawerLayout,                    /* DrawerLayout object */
            R.drawable.ic_drawer,             /* nav drawer image to replace 'Up' caret */
            R.string.navigation_drawer_open,  /* "open drawer" description for accessibility */
            R.string.navigation_drawer_close  /* "close drawer" description for accessibility */
    ) {
        @Override
        public void onDrawerClosed(View drawerView) {
            invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
        }
    };

    // Defer code dependent on restoration of previous instance state.
    // NB: required for the drawer indicator to show up!
    mDrawerLayout.post(new Runnable() {
        @Override
        public void run() {
            mDrawerToggle.syncState();
        }
    });

    mDrawerLayout.setDrawerListener(mDrawerToggle);
}

R.drawable.ic_drawer est en fait l'icône à utiliser comme indicateur. Vous pouvez le trouver dans Android Asset Studio ; voir Indicateur de tiroir de navigation .

Les références

  1. ActionBarDrawerToggle
  2. Création d'un tiroir de navigation
33
hardartcore

Android-Developer et HpTerm m'a aidé dans la bonne direction, en

  1. Soulignant que c'est en effet NavigationDrawer spécifique (que j'utilisais déjà comme dans l'exemple de Google)
  2. Dire où trouver l'icône ic_drawer.png (→ Android Asset Studio )

Maintenant, malheureusement, créer ActionBarDrawerToggle comme ci-dessous semble pas suffisant. Au moins sur mon appareil de test Nexus 7 (API 18).

drawerToggle = new ActionBarDrawerToggle(this, 
                       drawerLayout, 
                       R.drawable.ic_navigation_drawer, 
                       R.string.side_menu_open, 
                       R.string.side_menu_closed) {
    // ...
};

Solution partielle (API niveau 18+)

J'ai trouvé un moyen de faire apparaître l'indicateur: setHomeAsUpIndicator(). L'inconvénient: cette méthode a été ajoutée au niveau 18 de l'API.

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...
    getActionBar().setDisplayHomeAsUpEnabled(true); // also required
    if (Build.VERSION.SDK_INT >= 18) {
        getActionBar().setHomeAsUpIndicator(
            getResources().getDrawable(R.drawable.ic_navigation_drawer));
    }
}

Alors maintenant, la question demeure: comment faire fonctionner (dans mon cas) pour les niveaux d'API 14 à 17?

J'ai vérifié sur un appareil 4.1.2 (API 16) que l'icône ic_drawer N'apparaît pas . Avec setDisplayHomeAsUpEnabled(true) j'obtiens l'icône "home" normale (petite flèche pointant vers la gauche) et sans elle, l'espace laissé à l'icône de mon application reste vide.

Solution finale

Je l'ai fait fonctionner en utilisant la version éditée de Réponse du développeur Android .

Curieusement, ce qui manquait à mon code d'initialisation ActionBarDrawerToggle était le suivant:

   // Defer code dependent on restoration of previous instance state.
   drawerLayout.post(new Runnable() {
        @Override
        public void run() {
            mDrawerToggle.syncState();
        }
    });

Avec cela inclus, appeler setHomeAsUpIndicator() n'est pas nécessaire.

10
Jonik

Le mot clé ici est NavigationDrawer ; il y a un exemple de code de travail complet sur le site de développeur Android.

LIRE LA FIN DU LIEN DONNÉ : ouvrir et fermer avec l'icône de l'application

Le code suivant est copié à partir de là

public class MainActivity extends Activity {
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    ...

    public void onCreate(Bundle savedInstanceState) {
        ...

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(
                this,                  /* Host Activity */
                mDrawerLayout,         /* DrawerLayout object */
                R.drawable.ic_drawer,  /* nav drawer icon to replace 'Up' caret */
                R.string.drawer_open,  /* "open drawer" description */
                R.string.drawer_close  /* "close drawer" description */
                ) {

            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(mTitle);
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(mDrawerTitle);
            }
        };

        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
          return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }

    ...
}

Certains fichiers sont disponibles en téléchargement et les 3 petites lignes avec l'effet d'animation sont parfaitement illustrées.

Vous devez copier ces fichiers dans le dossier drawable correspondant. Selon le thème que vous utilisez, sombre ou clair, vous disposez d'un ensemble d'icônes différent.

Dans mon cas, j'ai simplement copié le drawer_shadow.9.png et ic_drawer.png dans le dossier drawable et a suivi l'exemple et tout fonctionne très bien.

Les icônes sont disponibles dans le lien que j'ai fourni, mais elles ne sont [~ # ~] pas [~ # ~] dans le "Pack d'icônes de la barre d'action" , ils se trouvent dans l'exemple d'application dans les dossiers res/drawable correspondants .

2
HpTerm