Même tiroir de navigation dans différentes activités

206

J'ai créé un tiroir de navigation fonctionnel comme indiqué dans le didacticiel sur le site Web developer.android.com . Mais maintenant, je veux utiliser un tiroir de navigation, j'ai créé dans le NavigationDrawer.class pour plusieurs activités dans mon application.

Ma question est, si quelqu'un ici peut faire un petit tutoriel, qui explique comment utiliser un tiroir de navigation pour plusieurs activités.

Je l'ai lu d'abord dans ce tiroir de navigation Android Answer sur plusieurs activités

mais cela n'a pas fonctionné sur mon projet

public class NavigationDrawer extends Activity {
public DrawerLayout drawerLayout;
public ListView drawerList;
private ActionBarDrawerToggle drawerToggle;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) {

        public void onDrawerClosed(View view) {
            getActionBar().setTitle(R.string.app_name);
        }

        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(R.string.menu);
        }
    };
    drawerLayout.setDrawerListener(drawerToggle);

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

    layers = getResources().getStringArray(R.array.layers_array);
    drawerList = (ListView) findViewById(R.id.left_drawer);
    View header = getLayoutInflater().inflate(R.layout.drawer_list_header, null);
    drawerList.addHeaderView(header, null, false);
    drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, android.R.id.text1,
            layers));
    View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
            R.layout.drawer_list_footer, null, false);
    drawerList.addFooterView(footerView);

    drawerList.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
            map.drawerClickEvent(pos);
        }
    });
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if (drawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);

}

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

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

Dans cette activité, je veux avoir le tiroir de navigation, donc j'étend «NavigationDrawer» et dans certaines autres activités, je veux utiliser le même tiroir de navigation

  public class SampleActivity extends NavigationDrawer {...}

Je ne sais pas quoi changer ...

MEX
la source
1
Vous pouvez trouver les exemples ici .
Naddy
1
vous pouvez trouver à partir de: stackoverflow.com/questions/33009469/…
varotariya vajsi

Réponses:

188

Si vous voulez un tiroir de navigation, vous devez utiliser des fragments. J'ai suivi ce tutoriel la semaine dernière et ça marche très bien:

http://developer.android.com/training/implementing-navigation/nav-drawer.html

Vous pouvez également télécharger un exemple de code à partir de ce didacticiel, pour voir comment procéder.


Sans fragments:

Voici votre code BaseActivity:

public class BaseActivity extends Activity
{
    public DrawerLayout drawerLayout;
    public ListView drawerList;
    public String[] layers;
    private ActionBarDrawerToggle drawerToggle;
    private Map map;

    protected void onCreate(Bundle savedInstanceState)
    {
        // R.id.drawer_layout should be in every activity with exactly the same id.
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) 
        {
            public void onDrawerClosed(View view) 
            {
                getActionBar().setTitle(R.string.app_name);
            }

            public void onDrawerOpened(View drawerView) 
            {
                getActionBar().setTitle(R.string.menu);
            }
        };
        drawerLayout.setDrawerListener(drawerToggle);

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

        layers = getResources().getStringArray(R.array.layers_array);
        drawerList = (ListView) findViewById(R.id.left_drawer);
        View header = getLayoutInflater().inflate(R.layout.drawer_list_header, null);
        drawerList.addHeaderView(header, null, false);
        drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, android.R.id.text1,
                layers));
        View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
                R.layout.drawer_list_footer, null, false);
        drawerList.addFooterView(footerView);

        drawerList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
                map.drawerClickEvent(pos);
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);

    }

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

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

Toutes les autres activités qui doivent avoir un tiroir de navigation doivent étendre cette activité au lieu de l'activité elle-même, par exemple:

public class AnyActivity extends BaseActivity
{
    //Because this activity extends BaseActivity it automatically has the navigation drawer
    //You can just write your normal Activity code and you don't need to add anything for the navigation drawer
}

XML

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <!-- Put what you want as your normal screen in here, you can also choose for a linear layout or any other layout, whatever you prefer -->
    </FrameLayout>
    <!-- The navigation drawer -->
    <ListView 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="#111"/>
</android.support.v4.widget.DrawerLayout>

Éditer:

J'ai moi-même rencontré quelques difficultés, alors voici une solution si vous obtenez NullPointerExceptions. Dans BaseActivity, remplacez la fonction onCreate par protected void onCreateDrawer(). Le reste peut rester le même. Dans les activités qui étendent BaseActivity, mettez le code dans cet ordre:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);
    super.onCreateDrawer();

Cela m'a aidé à résoudre mon problème, j'espère que ça aide!

C'est ainsi que vous pouvez créer un tiroir de navigation avec plusieurs activités, si vous avez des questions, n'hésitez pas à les poser.


Modifier 2:

Comme l'a dit @GregDan, vous BaseActivitypouvez également remplacer setContentView()et appeler onCreateDrawer:

@Override 
public void setContentView(@LayoutRes int layoutResID) 
{ 
    super.setContentView(layoutResID); 
    onCreateDrawer() ;
}
Kevin van Mierlo
la source
7
Je ne veux pas utiliser d'activités sur des fragments, je veux juste utiliser des activités différentes qui utilisent toutes le même tiroir de navigation. Je veux de l'activité, car là je peux utiliser différents types de mise en page comme la vue par balayage, la vue par carte ...
MEX
135
Avoir une seule activité peut être une tâche intimidante pour toute application assez complexe. L'utilisation des activités vous donne beaucoup de choses gratuites du système - c'est donc un point valide sur la façon d'utiliser plusieurs activités. Je ne peux pas imaginer une seule activité gérant la communication entre un certain nombre de combinaisons de fragments - cela ne fonctionnera tout simplement pas.
slott
1
Je suis désolé qu'il ait fallu si longtemps pour que je réponde. J'ai modifié ma réponse. Je pense que c'est le tutoriel que vous cherchiez. J'espère que cela t'aides.
Kevin van Mierlo
2
@KevinvanMierlo pouvez-vous me dire ce que vous entendez par: R.id.drawer_layout devrait être dans chaque activité avec exactement le même identifiant. Parce que j'ai fait exactement ce que vous avez dit ici et que je reçois une exception NullPointerException dans la méthode onCreate () de l'activité qui étend cette BaseActivity ..
Loolooii
1
@KevinvanMierlo btw, je pense que vous avez oublié ces 2 lignes? super.onCreate (savedInstanceState); setContentView (R.layout.activity_base);
Loolooii
34

J'ai trouvé la meilleure implémentation. C'est dans l'application Google I / O 2014 .

Ils utilisent la même approche que celle de Kevin. Si vous pouvez vous abstenir de tout ce qui n'est pas nécessaire dans l'application d'E / S, vous pouvez extraire tout ce dont vous avez besoin et Google est assuré que c'est une utilisation correcte du modèle de tiroir de navigation. Chaque activité a éventuellement un DrawerLayoutcomme sa disposition principale. La partie intéressante est de savoir comment la navigation vers d'autres écrans se fait. Il est implémenté BaseActivitycomme ceci:

private void goToNavDrawerItem(int item) {
        Intent intent;
        switch (item) {
            case NAVDRAWER_ITEM_MY_SCHEDULE:
                intent = new Intent(this, MyScheduleActivity.class);
                startActivity(intent);
                finish();
                break;

Cela diffère de la manière courante de remplacer le fragment actuel par une transaction de fragment. Mais l'utilisateur ne remarque aucune différence visuelle.

Coureur du vent
la source
Ce ^ je n'arrive pas à comprendre comment ils commencent de nouvelles activités et cela fonctionne parfaitement. C'est une grande application sur laquelle travailler.
hitch.united
@ hitch.united C'est parce qu'ils utilisent beaucoup de fragments et seulement quelques activités.
Joaquin Iurchuk
@ hitch.united, ils remplacent probablement l'animation de l'activité avec overridePendingTransitions.
EpicPandaForce
est le chargement de fragments au lieu d'activités de sous-classement?
Vikas Pandey
Voici le fichier d'octobre 2014: github.com/google/iosched/blob/…
denvercoder9
8

Cette réponse est donc en retard de quelques années, mais quelqu'un peut l'apprécier. Android nous a donné un nouveau widget qui facilite l'utilisation d'un tiroir de navigation avec plusieurs activités.

android.support.design.widget.NavigationView est modulaire et a sa propre disposition dans le dossier de menu. La façon dont vous l'utilisez consiste à encapsuler les dispositions xml de la manière suivante:

  1. La disposition racine est un android.support.v4.widget.DrawerLayout qui contient deux enfants: un <include ... />pour la mise en page qui est en train d'être encapsulée (voir 2) et un android.support.design.widget.NavigationView.

    <android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:openDrawer="start">
    
    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

nav_header_main est juste un LinearLayout avec orientation = vertical pour l'en-tête de votre Drawar de navigation.

activity_main_drawer est un menu xml dans votre répertoire res / menu. Il peut contenir des éléments et des groupes de votre choix. Si vous utilisez la galerie AndroidStudio, l'assistant en fera une de base pour vous et vous pourrez voir quelles sont vos options.

  1. La disposition de la barre d'application est généralement désormais un android.support.design.widget.CoordinatorLayout et cela comprendra deux enfants: un android.support.design.widget.AppBarLayout (qui contient un android.support.v7.widget.Toolbar) et un <include ... >pour votre contenu réel (voir 3).

    <android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="yourpackage.MainActivity">
    
     <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    
    </android.support.design.widget.AppBarLayout>
    
    <include layout="@layout/content_main" />

  2. La mise en page du contenu peut être la mise en page souhaitée. Il s'agit de la mise en page qui contient le contenu principal de l'activité (à l'exclusion du tiroir de navigation ou de la barre d'application).

Maintenant, la chose intéressante à propos de tout cela est que vous pouvez encapsuler chaque activité dans ces deux dispositions, mais que votre NavigationView (voir l'étape 1) pointe toujours vers activity_main_drawer (ou autre). Cela signifie que vous aurez le même (*) tiroir de navigation pour toutes les activités.

  • Ils ne seront pas la même instance de NavigationView mais, pour être honnête, cela n'était pas possible même avec la solution BaseActivity décrite ci-dessus.
jwehrle
la source
stackoverflow coupe certains des crochets xml qui les entourent, mais l'essentiel est là.
jwehrle
mais comment traitez-vous les fonctionnalités comme des boutons? vous devez écrire le même code dans chaque activité?
Laur89
Oui, car ce sont des instances distinctes. Cependant, vous pouvez créer une super classe pour étendre vos activités et y mettre ce code une fois.
jwehrle
@jwehrle pouvez-vous écrire un exemple sur la création d'une super classe pour nos activités?
CDrosos
La classe publique abstraite MyBaseActivity étend AppCompatActivity implémente NavigationView.OnNavigationItemSelectedListener {// implémente ce qui suit: Substitue public boolean onNavigationItemSelected (@NonNull MenuItem item) {}} classe publique MyActivity étend MyBaseActivity {}
jwehrle
7

Manière la plus simple de réutiliser un tiroir de navigation commun parmi un groupe d'activités

app_base_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <FrameLayout
        android:id="@+id/view_stub"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/menu_test"
        />
</android.support.v4.widget.DrawerLayout>

AppBaseActivity.java

/*
* This is a simple and easy approach to reuse the same 
* navigation drawer on your other activities. Just create
* a base layout that conains a DrawerLayout, the 
* navigation drawer and a FrameLayout to hold your
* content view. All you have to do is to extend your 
* activities from this class to set that navigation 
* drawer. Happy hacking :)
* P.S: You don't need to declare this Activity in the 
* AndroidManifest.xml. This is just a base class.
*/
import android.content.Intent;
import android.content.res.Configuration;
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.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

public abstract class AppBaseActivity extends AppCompatActivity implements MenuItem.OnMenuItemClickListener {
    private FrameLayout view_stub; //This is the framelayout to keep your content view
    private NavigationView navigation_view; // The new navigation view from Android Design Library. Can inflate menu resources. Easy
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private Menu drawerMenu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.app_base_layout);// The base layout that contains your navigation drawer.
        view_stub = (FrameLayout) findViewById(R.id.view_stub);
        navigation_view = (NavigationView) findViewById(R.id.navigation_view);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 0, 0);
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        drawerMenu = navigation_view.getMenu();
        for(int i = 0; i < drawerMenu.size(); i++) {
          drawerMenu.getItem(i).setOnMenuItemClickListener(this);
        }
        // and so on...
    }

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

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

    /* Override all setContentView methods to put the content view to the FrameLayout view_stub
     * so that, we can make other activity implementations looks like normal activity subclasses.
     */
    @Override
    public void setContentView(int layoutResID) {
        if (view_stub != null) {
            LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            View stubView = inflater.inflate(layoutResID, view_stub, false);
            view_stub.addView(stubView, lp);
        }
    }

    @Override
    public void setContentView(View view) {
        if (view_stub != null) {
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            view_stub.addView(view, lp);
        }
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        if (view_stub != null) {
            view_stub.addView(view, params);
        }
    }

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

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.item1:
                // handle it
                break;
            case R.id.item2:
                // do whatever
                break;
            // and so on...
        }
        return false;
    }
}
Levon Petrosyan
la source
Pouvez-vous fournir un exemple d'activité qui utilise cette activité de base?
CDrosos
Je ne me souviens pas vraiment des détails à ce sujet, je pense que l'extension AppBaseActivity et la setContentViewméthode par défaut devraient fonctionner.
Levon Petrosyan
6

Pour quiconque cherche à faire ce que l'affiche originale demande, veuillez envisager d'utiliser des fragments à la place de ce que Kevin a dit. Voici un excellent tutoriel sur la façon de procéder:

https://github.com/codepath/android_guides/wiki/Fragment-Navigation-Drawer

Si vous choisissez d'utiliser des activités au lieu de fragments, vous allez rencontrer le problème de la recréation du tiroir de navigation à chaque fois que vous accédez à une nouvelle activité. Il en résulte un rendu laid / lent du tiroir de navigation à chaque fois.

Micro
la source
5

Ma suggestion est: n'utilisez pas d'activités du tout, utilisez plutôt des fragments et remplacez-les dans le conteneur (disposition linéaire par exemple) où vous montrez votre premier fragment.

Le code est disponible dans les tutoriels pour développeurs Android, il vous suffit de le personnaliser.

http://developer.android.com/training/implementing-navigation/nav-drawer.html

Il est conseillé d'utiliser de plus en plus de fragments dans votre application, et il ne devrait y avoir que quatre activités de base locales à votre application, que vous mentionnez dans votre AndroidManifest.xml en dehors des externes (FacebookActivity par exemple):

  1. SplashActivity: n'utilise aucun fragment et utilise le thème FullScreen.

  2. LoginSignUpActivity: Ne nécessite pas du tout NavigationDrawer, et pas de bouton de retour également, alors utilisez simplement la barre d'outils normale, mais au moins, 3 ou 4 fragments seront nécessaires. Utilise le thème sans action

  3. Activité HomeActivity ou DashBoard: utilise un thème sans action. Ici, vous avez besoin du tiroir de navigation, tous les écrans qui suivent seront également des fragments ou des fragments imbriqués, jusqu'à la vue des feuilles, avec le tiroir partagé. Tous les paramètres, le profil utilisateur, etc. seront ici sous forme de fragments, dans cette activité. Les fragments ici ne seront pas ajoutés à la pile arrière et seront ouverts à partir des éléments du menu du tiroir. Dans le cas de fragments qui nécessitent un bouton de retour au lieu du tiroir, il y a un quatrième type d'activité ci-dessous.

  4. Activité sans tiroir. Cette activité a un bouton de retour en haut et les fragments à l'intérieur partageront la même barre d'action. Ces fragments seront ajoutés au back-stack, car il y aura un historique de navigation.

[Pour plus d'informations, voir: https://stackoverflow.com/a/51100507/787399 ]

Codage heureux !!

Abhinav Saxena
la source
Ceci est un post plus ancien. Vous pouvez utiliser des fragments pour vous assurer d'avoir toujours une activité. Vous continuez de remplacer les fragments dans un conteneur qui lui est dédié. Mettez dans la pile arrière lorsque vous avez besoin d'une navigation vers l'arrière, ou éclatez tous les fragments lorsque vous avez besoin qu'un fragment soit affiché comme premier.
Abhinav Saxena
@ Cabuxa.Mapache Veuillez vérifier le lien ci-joint à ma réponse pour obtenir de l'aide supplémentaire. J'ai pris une BaseActivity commune, qui aide à partager ActionBar ToolBar et NavigatonDrawer et d'autres composants dans tous les fragments qui y sont attachés.
Abhinav Saxena
1

mettre à jour ce code dans la baseactivity. et n'oubliez pas d'inclure tiroir_list_header dans votre xml d'activité.

super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
setContentView(R.layout.drawer_list_header);

et n'utilisez pas request () dans votre activité. mais le tiroir n'est toujours pas visible en cliquant sur l'image ... et en le faisant glisser sera visible sans les éléments de la liste. j'ai beaucoup essayé mais sans succès. besoin de quelques séances d'entraînement pour cela ...

MS Gadag
la source
1

Avec la réponse de @Kevin van Mierlo, vous êtes également capable d'implémenter plusieurs tiroirs. Par exemple, le menu par défaut situé sur le côté gauche (démarrer) et un autre menu optionnel, situé sur le côté droit, qui n'est affiché que lorsque des fragments déterminés sont chargés.

J'ai pu faire ça.

Russellhoff
la source
1
package xxxxxx;



import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.widget.SearchView;
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.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;


public class loginhome extends AppCompatActivity {
    private Toolbar toolbar;
    private NavigationView navigationView;
    private DrawerLayout drawerLayout;

    // Make sure to be using android.support.v7.app.ActionBarDrawerToggle version.
    // The android.support.v4.app.ActionBarDrawerToggle has been deprecated.
    private ActionBarDrawerToggle drawerToggle;

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

        // Initializing Toolbar and setting it as the actionbar
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        //Initializing NavigationView


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

        //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            // This method will trigger on item Click of navigation menu

            public boolean onNavigationItemSelected(MenuItem menuItem) {


                //Checking if the item is in checked state or not, if not make it in checked state
                if(menuItem.isChecked()) menuItem.setChecked(false);
                else menuItem.setChecked(true);

                //Closing drawer on item click
                drawerLayout.closeDrawers();

                //Check to see which item was being clicked and perform appropriate action
                switch (menuItem.getItemId()){


                    //Replacing the main content with ContentFragment Which is our Inbox View;
                    case R.id.nav_first_fragment:
                        Toast.makeText(getApplicationContext(),"First fragment",Toast.LENGTH_SHORT).show();
                         FirstFragment fragment = new FirstFragment();
                        android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.replace(R.id.frame,fragment);
                        fragmentTransaction.commit();
                        return true;

                    // For rest of the options we just show a toast on click
                    case R.id.nav_second_fragment:
                        Toast.makeText(getApplicationContext(),"Second fragment",Toast.LENGTH_SHORT).show();
                        SecondFragment fragment2 = new SecondFragment();
                        android.support.v4.app.FragmentTransaction fragmentTransaction2 = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction2.replace(R.id.frame,fragment2);
                        fragmentTransaction2.commit();
                        return true;

                    default:
                        Toast.makeText(getApplicationContext(),"Somethings Wrong",Toast.LENGTH_SHORT).show();
                        return true;

                }
            }
        });

        // Initializing Drawer Layout and ActionBarToggle
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.drawer_open, R.string.drawer_close){

            @Override
            public void onDrawerClosed(View drawerView) {
                // Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
                super.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                // Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank

                super.onDrawerOpened(drawerView);
            }
        };

        //Setting the actionbarToggle to drawer layout
        drawerLayout.setDrawerListener(actionBarDrawerToggle);

        //calling sync state is necessay or else your hamburger icon wont show up
        actionBarDrawerToggle.syncState();







    }

utilisez ceci pour votre toolbar.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:background="@color/colorPrimary"
        android:elevation="4dp"
        android:id="@+id/toolbar"
        android:theme="@style/ThemeOverlay.AppCompat.Dark"


        >

    </android.support.v7.widget.Toolbar>

utilisez-le pour l'en-tête de navigation si vous souhaitez l'utiliser

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="192dp"
    android:background="?attr/colorPrimaryDark"
    android:padding="16dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:orientation="vertical"
    android:gravity="bottom">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:id="@+id/navhead"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:textColor="#ffffff"
            android:text="tanya"
            android:textSize="14sp"
            android:textStyle="bold"

            />

        <TextView
            android:id="@+id/email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="5dp"
            android:text="tanya.com"
            android:textSize="14sp"
            android:textStyle="normal"

            />
    </LinearLayout>
    <de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_below="@+id/imageView"
        android:layout_marginTop="15dp"

        android:src="@drawable/face"
        android:id="@+id/circleView"
        />



</RelativeLayout>
Volverine
la source
1

Je le fais à Kotlin comme ceci:

open class BaseAppCompatActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

protected lateinit var drawerLayout: DrawerLayout
protected lateinit var navigationView: NavigationView
@Inject
lateinit var loginService: LoginService

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Log.d("BaseAppCompatActivity", "onCreate()")
    App.getComponent().inject(this)
    drawerLayout = findViewById(R.id.drawer_layout) as DrawerLayout

    val toolbar = findViewById(R.id.toolbar) as Toolbar
    setSupportActionBar(toolbar)

    navigationView = findViewById(R.id.nav_view) as NavigationView
    navigationView.setNavigationItemSelectedListener(this)

    val toggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)

    drawerLayout.addDrawerListener(toggle)
    toggle.syncState()
    toggle.isDrawerIndicatorEnabled = true

    val navigationViewHeaderView = navigationView.getHeaderView(0)
    navigationViewHeaderView.login_txt.text = SharedKey.username
}
private inline fun <reified T: Activity> launch():Boolean{
    if(this is T) return closeDrawer()
    val intent = Intent(applicationContext, T::class.java)
    startActivity(intent)
    finish()
    return true
}

private fun closeDrawer(): Boolean {
    drawerLayout.closeDrawer(GravityCompat.START)
    return true
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
    val id = item.itemId

    when (id) {
        R.id.action_tasks -> {
            return launch<TasksActivity>()
        }
        R.id.action_contacts -> {
            return launch<ContactActivity>()
        }
        R.id.action_logout -> {
            createExitDialog(loginService, this)
        }
    }
    return false
}
}

Les activités du tiroir doivent en hériter BaseAppCompatActivity, appeler super.onCreateaprès que le contenu est défini (en fait, peut être déplacé vers une méthode init) et avoir des éléments correspondants pour les identifiants dans leur mise en page

Pavlus
la source
Je voulais essayer votre solution mais j'obtiens cette erreur: "Cette activité a déjà une barre d'action fournie par le décor de fenêtre". Je veux basculer entre 3 activités et chacune a sa propre barre d'application. Pensez-vous que c'est possible?
davoid
Je pense que vous devez déplacer votre barre d'action en fragments dans ce cas. Dans notre application, nous avons utilisé le thème NoActionBar et fourni une barre d'outils pour la compatibilité, pour autant que je m'en souvienne.
Pavlus
@Pavlus à quoi ressemblerait le code lors de la deuxième activité? class trackActivity: BaseAppCompatActivity () {?
Craig P
0

Ma réponse est juste conceptuelle sans aucun code source. Il pourrait être utile pour certains lecteurs comme moi de comprendre.

Cela dépend de votre approche initiale sur la façon dont vous architecturez votre application. Il existe essentiellement deux approches.

  1. Vous créez une activité (activité de base) et toutes les autres vues et écrans seront des fragments. Cette activité de base contient l'implémentation des dispositions de tiroir et de coordinateur. C'est en fait ma façon préférée de faire, car avoir de petits fragments autonomes rendra le développement d'applications plus facile et plus fluide.

  2. Si vous avez commencé le développement de votre application avec des activités, une pour chaque écran, vous créerez probablement une activité de base et toutes les autres activités en découleront. L'activité de base contiendra le code pour la mise en œuvre du tiroir et du coordinateur. Toute activité nécessitant une implémentation de tiroir peut s'étendre à partir de l'activité de base.

Je préférerais personnellement éviter d'utiliser des fragments et des activités mixtes sans aucune organisation. Cela rend le développement plus difficile et vous bloque finalement. Si vous l'avez fait, refactorisez votre code.

Farruh Habibullaev
la source
-1

Créez un tiroir de navigation dans votre MainActivity à l'aide d'un fragment.
Initialisez le tiroir de navigation dans MainActivity
maintenant dans toutes les autres activités que vous souhaitez utiliser le même tiroir de navigation. Définissez simplement android: nom dans votre fragment pointant vers votre fichier Java de fragment. Vous n'aurez pas besoin d'initialiser le fragment dans d'autres activités.
Vous pouvez accéder à Nav Drawer en glissant dans d'autres activités comme dans l'application Google Play Store

droidlabel
la source