web-dev-qa-db-fra.com

DrawerLayout Double Drawer (Tiroirs gauche et droit simultanément)

J'ai une application dans laquelle je souhaite implémenter un double tiroir - un de gauche et un de droite. Le tiroir de gauche sert à la navigation dans les applications, le tiroir de droite au filtrage des résultats.

Donc, la disposition est comme ça:

<?xml version="1.0" encoding="utf-8"?>
<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">

    <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="@color/light_grey"
        Android:orientation="vertical">

        <GridView
            Android:id="@+id/gridview"
            style="@style/GridViewStyle"
            Android:layout_width="fill_parent"
            Android:layout_height="fill_parent"
            Android:gravity="center"
            Android:horizontalSpacing="7dp"
            Android:stretchMode="columnWidth"
            Android:verticalSpacing="7dp" />
    </LinearLayout>

    <ListView
        Android:id="@+id/left_drawer"
        Android:layout_width="240dp"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"
        Android:background="#111"
        Android:choiceMode="singleChoice"
        Android:divider="@Android:color/transparent"
        Android:dividerHeight="0dp" />

    <ListView
        Android:id="@+id/right_drawer"
        Android:layout_width="240dp"
        Android:layout_height="match_parent"
        Android:layout_gravity="end"
        Android:background="#111"
        Android:choiceMode="singleChoice"
        Android:divider="@Android:color/transparent"
        Android:dividerHeight="0dp" />
</Android.support.v4.widget.DrawerLayout>

Vous pouvez clairement voir ici "left_drawer" et "right_drawer", ainsi que leur gravité respective - "début" et "fin". Et cela fonctionne réellement! Vous pouvez les sortir tous les deux.

Le problème est que, lorsque j'implémente DrawerToggle - il n'ouvre que le tiroir de gauche et ne ferme pas celui de droite. Si le tiroir de droite est ouvert et que j'appuie sur le bouton DrawerToggle - le tiroir de gauche s'ouvre AUSSI et chevauche le tiroir de droite. .

Il y a plusieurs solutions que j'essaie de trouver:

  1. Créez le même bouton DrawerToggle sur le côté droit, avec le même comportement et la même animation que le côté gauche.
  2. Faites le tiroir sur le côté opposé du tiroir que je tente d’ouvrir - se ferme automatiquement (si le tiroir de gauche est ouvert et que j’appuie sur la bascule du tiroir de droite et inversement).

Et je n'ai pas compris comment faire cela, car DrawerToggle accepte le DrawerLayout lui-même en tant que paramètre, et non les tiroirs individuels ...

J'utilise la bibliothèque de support.

Quelqu'un a des idées? Merci d'avance.

63
ExiRouS

Vous pouvez l'appeler comme ceci dans le gestionnaire d'un ToggleButton, par exemple:

mDrawerLayout.openDrawer(mDrawer);
mDrawerLayout.closeDrawer(mDrawer);

Où mDrawer est une référence au tiroir spécifique que vous devez ouvrir (que ce soit une vue ou une mise en page), dans votre cas, le ListView que vous souhaitez afficher.

23
Armel Larcier

Voici le code d'une activité à tiroir double pouvant être étendu par d'autres activités pour implémenter le tiroir double, en supposant que leur présentation est similaire à celle proposée par OP.

    public class DoubleDrawerActivity extends ActionBarActivity {

    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private View mLeftDrawerView;
    private View mRightDrawerView;

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

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

    @Override
    protected void onStart() {
        super.onStart();

        if(mDrawerLayout == null || mLeftDrawerView == null || mRightDrawerView == null || mDrawerToggle == null) {
            // Configure navigation drawer
            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
            mLeftDrawerView = findViewById(R.id.left_drawer);
            mRightDrawerView = findViewById(R.id.right_drawer);
            mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_navigation_drawer, R.string.drawer_open, R.string.drawer_close) {

                /** Called when a drawer has settled in a completely closed state. */
                public void onDrawerClosed(View drawerView) {
                    if(drawerView.equals(mLeftDrawerView)) {
                        getSupportActionBar().setTitle(getTitle());
                        supportInvalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                        mDrawerToggle.syncState();
                    }
                }

                /** Called when a drawer has settled in a completely open state. */
                public void onDrawerOpened(View drawerView) {
                    if(drawerView.equals(mLeftDrawerView)) {
                        getSupportActionBar().setTitle(getString(R.string.app_name));
                        supportInvalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                        mDrawerToggle.syncState();
                    }                   
                }

                @Override
                public void onDrawerSlide(View drawerView, float slideOffset) {
                    // Avoid normal indicator glyph behaviour. This is to avoid glyph movement when opening the right drawer
                    //super.onDrawerSlide(drawerView, slideOffset);
                }
            };

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

    @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 onPrepareOptionsMenu(Menu menu) {

        // If the nav drawer is open, hide action items related to the content view
        for(int i = 0; i< menu.size(); i++)
            menu.getItem(i).setVisible(!mDrawerLayout.isDrawerOpen(mLeftDrawerView));

        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch(item.getItemId()) {
            case Android.R.id.home:
                mDrawerToggle.onOptionsItemSelected(item);

                if(mDrawerLayout.isDrawerOpen(mRightDrawerView))
                    mDrawerLayout.closeDrawer(mRightDrawerView);

                return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
36

Vous pouvez utiliser NavigationView depuis la conception du matériau.

<?xml version="1.0" encoding="utf-8"?>
<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" />

    <Android.support.design.widget.NavigationView
        Android:id="@+id/nav_view2"
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"
        Android:layout_gravity="end"
        Android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer1" />

</Android.support.v4.widget.DrawerLayout>

pour plus d'informations, veuillez vous reporter http://v4all123.blogspot.in/2016/03/simple-example-of-navigation-view-on.html

9
Gunaseelan

Voici ma solution courte pour tous ceux qui veulent empêcher l'animation de l'indicateur de tiroir s'ils glissent la vue de droite. Implémentez simplement la méthode onDrawerSlide comme ceci.

mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer_white, 0, 0) {

    @Override
    public void onDrawerClosed(View view) {
       invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
    }

    @Override
    public void onDrawerOpened(View drawerView) {
       invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
    }

    @Override
    public void onDrawerSlide(View drawerView, float slideOffset) {
       if (drawerView == mSlidingMenuNavigationList) {
           super.onDrawerSlide(drawerView, slideOffset);
       }
       else {
          // do nothing on all other views
       }
    }
};
6
Kai Burghardt

Utilisez la constante de gravité (Gravity.LEFT ou Gravity.RIGHT) du tiroir que vous souhaitez fermer (lorsque vous ouvrez l’autre) dans onOptionsItemSelected (), comme indiqué ci-dessous.

public boolean onOptionsItemSelected(MenuItem item) {
    if (mDrawerToggle.onOptionsItemSelected(item)) {

       // Close the right side drawer if visible
       if(mDrawerLayout.isDrawerVisible(Gravity.RIGHT)) {
           mDrawerLayout.closeDrawer(Gravity.RIGHT);
       }
       return true;
    }

    // Regular stuff
    switch (item.getItemId()) {
    case R.id.action_example:
        Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();
        return true;
    }

    return super.onOptionsItemSelected(item);
}

mDrawerToggle = Objet d'écoute implémentant DrawerLayout.DrawerListener
Voir: http://developer.Android.com/reference/Android/support/v4/app/ActionBarDrawerToggle.html

5
Himanshu Likhyani

J'ai résolu d'ajouter ce code dans la méthode onOptionsItemSelected:

switch (item.getItemId()) {
    case Android.R.id.home:
        if (mDrawerLayout.isDrawerOpen(mDrawerList_right)){
            mDrawerLayout.closeDrawer(mDrawerList_right);
        }
        mDrawerLayout.openDrawer(mDrawerList_left);
    }
    break;
case R.id.action_drawer:
        if (mDrawerLayout.isDrawerOpen(mDrawerList_left)){
            mDrawerLayout.closeDrawer(mDrawerList_left);
        }
        mDrawerLayout.openDrawer(mDrawerList_right);
    }
default:
    break;
}

J'ai ajouté un bouton d'action et remplacé le bouton d'accueil de la barre d'actions

0
Francesco Ditrani

confectionnez un objet personnalisé et ajoutez-le à droite, passez-lui le tiroir approprié.

final ToggleButton ic_nav = (ToggleButton) customNav.findViewById(R.id.ic_nav);

        ic_nav.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View arg0)
            {
                if ( mDrawerLayout.isDrawerOpen(mDrawerList) && arg0.isSelected()) {
                    mDrawerLayout.closeDrawer(mDrawerList);
                    arg0.setSelected(false);
                }
                else if (!mDrawerLayout.isDrawerOpen(mDrawerList) && !arg0.isSelected()){
                    mDrawerLayout.openDrawer(mDrawerList);
                    ic_nav.setSelected(false);
                    arg0.setSelected(true);
                }
            }
        });
0
mhdtouban