66 votes

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

J'ai une application dans laquelle je veux mettre en œuvre un double tiroir - un à partir de la gauche et de la droite. Tiroir gauche est pour app de navigation, à droite du tiroir est pour le filtrage de résultats.

Ainsi, la mise en page ressemble à ceci:

<?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:orientation="vertical"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="@color/light_grey"
            >
        <GridView android:id="@+id/gridview"
                  android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:verticalSpacing="7dp"
                  android:horizontalSpacing="7dp"
                  android:stretchMode="columnWidth"
                  android:gravity="center"
                  style="@style/GridViewStyle"/>
    </LinearLayout>
    <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"/>
    <ListView android:id="@+id/right_drawer"
              android:layout_width="240dp"
              android:layout_height="match_parent"
              android:layout_gravity="end"
              android:choiceMode="singleChoice"
              android:divider="@android:color/transparent"
              android:dividerHeight="0dp"
              android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

Vous pouvez clairement voir ici "left_drawer" et "right_drawer", et de leur gravité "début" et "fin" Et cela fonctionne réellement! Vous pouvez retirer les deux.

Le problème c'est que quand je mets en œuvre la DrawerToggle - il ne s'ouvre le tiroir gauche, et ne ferme pas la bonne, donc si le tiroir est ouvert et je presse le DrawerToggle bouton gauche tiroirs s'ouvre ÉGALEMENT, et chevauche le droit de tiroir.

Il ya un couple de solutions je suis d'essayer d'obtenir:

  1. Faire la même DrawerToggle bouton sur le côté droit, avec le même comportement et de l'animation que pour le côté gauche.
  2. Faire le tiroir sur le côté opposé du tiroir, je suis en train d'ouvrir - fermer automatiquement (si le tiroir gauche est ouverte et que j'appuie sur l'interrupteur de droite tiroir et vice-versa).

Et je n'ai pas compris comment le faire, parce que DrawerToggle accepte la DrawerLayout lui-même en tant que paramètre, et non de la personne tiroirs...

Je suis l'aide de la Bibliothèque de prise en charge.

N'importe qui ont des idées? Je vous remercie à l'avance.

36voto

Voici le code d'une activité Double tiroir pouvant être étendu par d'autres activités pour implémenter le double tiroir, 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);
}
 

}

25voto

Armel Larcier Points 5391

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.

6voto

Kai Burghardt Points 121

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

5voto

CodeRat Points 1718

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

0voto

Francesco Ditrani Points 106

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X