web-dev-qa-db-fra.com

Android: tiroir de navigation / activités multiples / même menu

Ce que j'essaie de faire, c'est d'avoir un menu NavigationDrawer comme ceci: NavigationDrawer

J'ai compris comment modifier les dispositions lorsque l'on clique sur les éléments du menu, mais comment charger une nouvelle activité sans perdre le menu?

Ma principale question:

Par exemple, disons qu'une de mes options de menu vous amène à une disposition où il y a des boutons qui font quelque chose. J'ai besoin de charger une activité/classe d'accompagnement, qui gérera les actions et les fonctionnalités de cette "page" spécifique dans l'application. Si une autre option de menu vous amène à une mise en page avec seulement une image, par exemple, ce serait une autre activité sans tout ce code qui gère la fonctionnalité des boutons, car il n'y a pas de boutons dans cet écran.

J'espère que cela à du sens! J'ai suivi de nombreux tutoriels/vidéos en ligne en utilisant plusieurs méthodes (Fragments etc.) mais rien n'a tout à fait répondu à ma question.

14
L. Zan

D'après ce que je comprends, vous voulez que le tiroir de navigation soit présent dans chaque activité. Il existe deux méthodes:

  1. Utilisez la réponse de @ Russell. Faites une activité principale avec un framelayout généralement appelé content_frame qui couvre toute l'activité. Cette activité a le code du tiroir de navigation. Au clic sur le bouton, vous pouvez remplacer le contenu de cette mise en page par la mise en page du fragment souhaité (c'est-à-dire soit un fragment avec plusieurs boutons, soit une image). Les éléments du tiroir sont donc tous des fragments. Dans les tutoriels, les fragments sont appelés via getFragmentManager (). Découvrez la série de vidéos sur le tiroir de navigation de ces gars, slidenerd: https://www.youtube.com/watch?v=K8hSIP2ha-g . Essayez de l'implémenter au fil de la vidéo

  2. Personnellement, je préfère cette méthode mais elle a ses limites. Créez une activité de base dans laquelle se trouve le code du tiroir de navigation. Cela a un framelayout généralement appelé content_frame qui couvre toute l'activité. Les activités qui doivent avoir le tiroir étendent cette activité de base au lieu de la compatibilité ou de l'activité d'application. L'inflation de la disposition fonctionne comme ceci dans le oncreate: getLayoutInflater().inflate(R.layout.activity_this, contentFrameLayout); au lieu de setContentView. Ici, les activités sont démarrées via startActivity.

Inconvénients de la 2ème méthode:

a) La BaseActivity est détruite et recréée chaque fois que l'utilisateur change d'activité.

b) L'activité ne peut étendre qu'une seule classe qui devient par défaut baseActivity

Avantages de la 2ème méthode:

a) Vous pouvez maintenir une pile d'activités

b) Chaque activité peut avoir ses propres règles de changement de configuration et règles onsaveInstance.

c) Ces activités peuvent avoir des fragments séparés, qui utilisent cette activité pour la communication. Essayer de le faire dans la première méthode impliquerait une activité principale implémentant un grand nombre d'interfaces inutilement (vous en apprendrez plus sur les interfaces dans la communication inter-fragments)

23
suku

Grâce aux réponses ci-dessus, j'ai pu faire exactement ce que je voulais, voici exactement ce que j'ai fait pour quiconque le recherche à l'avenir:

Mon activity_main.xml ressemble à ceci:

<!--When the DrawerLayout is the root layout, the first child-->
<!--of that layout is the contents of the main screen, and the-->
<!--second child is the contents of the menu-->

<!--First child layout-->

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical">

    <include
        layout="@layout/toolbar_layout"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" />

    <FrameLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:id="@+id/content_frame"/>

</LinearLayout>

<!--Second child layout-->
<Android.support.design.widget.NavigationView
    Android:id="@+id/navigation_view"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_gravity="start"
    app:headerLayout="@layout/navigation_drawer_header"
    app:menu="@menu/drawer_menu">

</Android.support.design.widget.NavigationView>

Il s'agit du DrawerLayout standard qui rassemble tous les morceaux du menu NavigationDrawer. L'ajout important à cela est le bit FrameLayout ... auquel j'ai donné l'ID content_frame. C'est là que toutes les autres dispositions utilisées par d'autres activités seront poussées/ajoutées/gonflées.

Mon BaseActivity.Java ressemble à ceci:

package com.example.test;
import Android.content.Intent;
import Android.os.Bundle;
import Android.support.design.widget.NavigationView;
import Android.support.v4.widget.DrawerLayout;
import Android.support.v7.app.ActionBarDrawerToggle;
import Android.support.v7.app.AppCompatActivity;
import Android.support.v7.widget.Toolbar;
import Android.view.MenuItem;

public class BaseActivity extends AppCompatActivity {

    DrawerLayout drawerLayout;
    ActionBarDrawerToggle actionBarDrawerToggle;
    Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_view);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_closed);
        drawerLayout.setDrawerListener(actionBarDrawerToggle);

        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem item) {
                switch (item.getItemId()) {

                    case R.id.menu_home:
                        Intent anIntent = new Intent(getApplicationContext(), TheClassYouWantToLoad.class);
                        startActivity(loadPlayer);
                        drawerLayout.closeDrawers();
                        break;

                }
                return false;
            }
        });

    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        actionBarDrawerToggle.syncState();
    }

}

Maintenant, dans la méthode onNavigationItemSelected, il existe une instruction switch qui gère ce qui se passe lorsque chaque élément de menu est sélectionné. C'est le bit important:

Intent anIntent = new Intent(getApplicationContext(), TheClassYouWantToLoad.class);
startActivity(anIntent);
drawerLayout.closeDrawers(); 

Vous devez remplacer "TheClassYouWantToLoad" par votre propre classe. Maintenant, dans cette nouvelle classe (qui nécessite probablement le chargement de nouveaux éléments d'interface utilisateur), vous avez besoin des éléments suivants:

public class TheClassYouWantToLoad extends BaseActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

FrameLayout contentFrameLayout = (FrameLayout) findViewById(R.id.content_frame); //Remember this is the FrameLayout area within your activity_main.xml
getLayoutInflater().inflate(R.layout.the_layout_you_want_to_load, contentFrameLayout);
    }
}

et remplacez "the_layout_you_want_to_load" par le nom de la mise en page que vous souhaitez charger.

45
L. Zan

Si vous démarrez une nouvelle activité, vous perdrez votre menu car la nouvelle activité couvrira l'ancienne activité. Vous devez utiliser des fragments pour cela. Considérez les fragments comme des activités qui peuvent vivre dans une autre activité.

Utilisez des fragments, mais ajoutez vos éléments d'interface utilisateur à la présentation d'activité en dehors du FrameLayout (id: content_frame), puis lorsque vous cliquez sur un élément de menu, votre transaction de fragment n'affectera que le content_frame FrameLayout, laissant tous les autres éléments de présentation en place.

Accrochez-vous, mon pote, ça devient plus clair d'ici ... jusqu'à ce que vous atteigniez le mur suivant: D

Je suggère ce tutoriel: https://www.udacity.com/course/viewer#!/c-ud853/l-1395568821

Et ce matériel: http://developer.Android.com/training/implementing-navigation/nav-drawer.html

2
Russell Elfenbein