web-dev-qa-db-fra.com

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

J'ai créé un tiroir de navigation comme dans le didacticiel du developer.Android.com website. Mais maintenant, je veux utiliser un tiroir de navigation, créé dans le fichier NavigationDrawer.class pour plusieurs activités dans mon application.

Ma question est la suivante: si quelqu'un ici peut créer un petit didacticiel expliquant comment utiliser un tiroir de navigation pour plusieurs activités.

Je l'ai d'abord lu à ce Answer tiroir de navigation Android 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 souhaite disposer du tiroir de navigation, donc je développe "NavigationDrawer". Dans d'autres activités, je souhaite utiliser le même tiroir de navigation. 

  public class SampleActivity extends NavigationDrawer {...}

Je ne sais pas quoi changer ...

187
MEX

Si vous voulez un tiroir de navigation, vous devriez utiliser des fragments ... J'ai suivi ce tutoriel la semaine dernière et cela fonctionne 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 tutoriel pour voir comment procéder.


Sans fragments:

Ceci est 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 nécessitant 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>

Modifier:

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

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

Cela m'a aidé à résoudre mon problème, espérons que cela aide!

Voici comment vous pouvez créer un tiroir de navigation avec plusieurs activités. Si vous avez des questions, n'hésitez pas.


Edit 2:

Comme l'a dit @GregDan, votre BaseActivity peut également remplacer setContentView() et appeler onCreateDrawer à cet emplacement:

@Override 
public void setContentView(@LayoutRes int layoutResID) 
{ 
    super.setContentView(layoutResID); 
    onCreateDrawer() ;
}
169
Kevin van Mierlo

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

Ils utilisent la même approche que celle de Kevin. Si vous pouvez vous abstenir de tous les éléments inutiles de l'application I/O, vous pouvez extraire tout ce dont vous avez besoin et Google assure que l'utilisation du motif de tiroir de navigation est correcte. Chaque activité a éventuellement une DrawerLayout comme disposition principale. La partie intéressante concerne la manière dont la navigation vers les autres écrans est effectuée. Il est implémenté dans BaseActivity comme 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 habituelle de remplacer le fragment actuel par une transaction de fragment. Mais l'utilisateur ne voit pas de différence visuelle.

34
WindRider

Donc, cette réponse a quelques années de retard mais quelqu'un peut l'apprécier. Android nous a fourni un nouveau widget qui facilite l’utilisation d’un tiroir de navigation avec plusieurs activités.

Android.support.design.widget.NavigationView est modulaire et possède sa propre présentation dans le dossier du menu. La façon dont vous l'utilisez est d'encapsuler les dispositions xml de la manière suivante:

  1. Root Layout est un fichier Android.support.v4.widget.DrawerLayout contenant deux enfants: un <include ... /> pour la mise en page en cours d'encapsulation (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 tableau 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 créera une de base et vous pourrez voir quelles sont vos options.

  1. La présentation de la barre d'applications est généralement désormais un Android.support.design.widget.CoordinatorLayout, qui inclut deux enfants: un Android.support.design.widget.AppBarLayout (qui contient un Android.support.v7.widget.Toolbar) et un <include ... > pour votre contenu actuel (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 disposition du contenu peut être celle que vous voulez. Il s'agit de la présentation qui contient le contenu principal de l'activité (à l'exclusion du tiroir de navigation ou de la barre d'applications).

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 sur activity_main_drawer (ou autre chose). Cela signifie que vous aurez le même tiroir de navigation (*) pour toutes les activités.

  • Ce ne sera pas la même instance de NavigationView mais, pour être juste, cela n’était pas possible même avec la solution BaseActivity décrite ci-dessus.
7
jwehrle

Si vous souhaitez faire ce que l'affiche originale demande, utilisez plutôt des fragments comme le dit Kevin. Voici un excellent tutoriel sur la façon de le faire:

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

Si vous choisissez plutôt 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 naviguez vers une nouvelle activité. Il en résulte un rendu laid/lent du tiroir de navigation à chaque fois. 

7
Micro

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

Le code est disponible dans Android Developer Tutorials, 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, que vous mentionnez dans votre AndroidManifest.xml en dehors des activités externes (FacebookActivity par exemple):

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

  2. LoginSignUpActivity: ne nécessite pas du tout NavigationDrawer, et ne contient pas non plus de bouton Précédent; utilisez simplement la barre d’outils normale, mais au moins 3 ou 4 fragments seront nécessaires. Utilise le thème no-action-bar

  3. Activité HomeActivity ou DashBoard: utilise le thème no-action-bar. Ici, vous avez besoin du tiroir de navigation. Tous les écrans suivants sont des fragments ou des fragments imbriqués, jusqu’à la vue en feuille, avec le tiroir partagé. Tous les paramètres, le profil utilisateur, etc. seront ici en tant que fragments, dans cette activité . Les fragments ici ne seront pas ajoutés à la pile arrière et seront ouverts à partir des éléments de menu du tiroir. Dans le cas de fragments nécessitant le bouton retour au lieu du tiroir, il existe 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'actions. Ces fragments seront ajoutés à la pile arrière, car il y aura un historique de navigation.

[Pour plus de précisions, voir: https://stackoverflow.com/a/51100507/787399 ]

Bonne codage !!

5
Abhinav Saxena

Meilleure façon 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;
    }
}
3
Levon Petrosyan
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 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>
1
Volverine

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

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 essayé beaucoup mais sans succès. besoin de quelques séances d'entraînement pour cela ...

1
M S Gadag

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 hériter de cette BaseAppCompatActivity, appeler super.onCreate une fois le contenu défini (en fait, peut être déplacé vers une méthode init) et avoir des éléments correspondants pour les identifiants dans leur présentation

1
Pavlus

Avec la réponse de @Kevin van Mierlo, vous êtes également capable de mettre en œuvre plusieurs tiroirs. Par exemple, le menu par défaut situé sur le côté gauche (début) et un autre menu facultatif situé sur le côté droit, qui s'affiche uniquement lorsque des fragments déterminés sont chargés.

J'ai été capable de faire ça.

1
russellhoff

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

Cela dépend de votre approche initiale de l'architecture de votre application. Il existe essentiellement deux approches. 

  1. Vous créez une activité (activité de base) et toutes les autres vues et tous les écrans sont des fragments. Cette activité de base contient la mise en œuvre pour les dispositions de tiroir et de coordinateur. C’est en fait la méthode que je préfère, car le fait de disposer de petits fragments autonomes facilitera et facilitera le développement des applications.

  2. Si vous avez démarré le développement de votre application avec des activités, une pour chaque écran, vous créerez probablement une activité de base. L'activité de base contiendra le code pour l'implémentation du tiroir et du coordinateur. Toute activité nécessitant une implémentation de tiroir peut s’étendre de l’activité de base.

Personnellement, je préférerais éviter d’utiliser des fragments et des activités mélangées sans aucune organisation. Cela rend le développement plus difficile et vous bloque finalement. Si vous l'avez fait, refactorisez votre code.

0
Farruh Habibullaev