web-dev-qa-db-fra.com

Comment détecter que le DrawerLayout a commencé à s'ouvrir?

J'ai donc des onglets que je veux masquer lorsque le tiroir de navigation commence ouverture. Le code que j'ai les cache quand il a fini de s'ouvrir, mais ce n'est pas ce que je veux.

mDrawerToggle = new ActionBarDrawerToggle(
        this,                 
        mDrawerLayout,        
        R.drawable.ic_drawer,  
        R.string.drawer_open,  
        R.string.drawer_close  
) {
    @Override
    public void onDrawerClosed(View view) {
        invalidateOptionsMenu(); 
        setActionBarMode(ActionBar.NAVIGATION_MODE_TABS);
    }

    @Override
    public void onDrawerOpened(View drawerView) {
        invalidateOptionsMenu(); 
        setActionBarMode(ActionBar.NAVIGATION_MODE_STANDARD);
    }

};
mDrawerLayout.setDrawerListener(mDrawerToggle);

Voici ce que j'ai essayé:

  • Définir une onClickListener à mDrawerLayout. onClick ne se fait jamais appeler
  • Définir une onTouchListener à mDrawerLayout. onTouch ne se fait jamais appeler
  • Recherche ActionBarDrawerToggle et DrawerLayout classes. Impossible de trouver quelque chose comme onDrawerStartedOpening.
39
Oleksiy

Il y a 2 façons possibles de le faire:

1) Utiliser onDrawerSlide(View drawerView, float slideOffset) callback

slideOffset passe de 0 à 1. 1 signifie qu'il est complètement ouvert, 0 - fermé. 

Une fois le décalage passé de 0 à !0 - cela signifie que le processus d’ouverture a commencé. Quelque chose comme:

mDrawerToggle = new ActionBarDrawerToggle(
        this,                 
        mDrawerLayout,        
        R.drawable.ic_drawer,  
        R.string.drawer_open,  
        R.string.drawer_close  
) {

    @Override
    public void onDrawerSlide(View drawerView, float slideOffset) {
        if (slideOffset == 0
                && getActionBar().getNavigationMode() == ActionBar.NAVIGATION_MODE_STANDARD) {
            // drawer closed
            getActionBar()
                    .setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
            invalidateOptionsMenu();
        } else if (slideOffset != 0
                && getActionBar().getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
            // started opening
            getActionBar()
                    .setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
            invalidateOptionsMenu();
        }
        super.onDrawerSlide(drawerView, slideOffset);
    }
};
mDrawerLayout.setDrawerListener(mDrawerToggle);

2) Utiliser onDrawerStateChanged(int newState) callback

Vous devez écouter STATE_SETTLING states - cet état est signalé dès que le tiroir commence à bouger (qu'il s'ouvre ou se ferme). Donc, une fois que vous voyez cet état - vérifiez si le tiroir est ouvert maintenant et agissez en conséquence:

mDrawerToggle = new ActionBarDrawerToggle(
        this,                 
        mDrawerLayout,        
        R.drawable.ic_drawer,  
        R.string.drawer_open,  
        R.string.drawer_close  
) {
    @Override
    public void onDrawerStateChanged(int newState) {
        if (newState == DrawerLayout.STATE_SETTLING) {
            if (!isDrawerOpen()) {
                // starts opening
                getActionBar()
                        .setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
            } else {
                // closing drawer
                getActionBar()
                        .setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
            }
            invalidateOptionsMenu();
        }
    }
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
67
Pavel Dudka

La réponse actuellement acceptée par Pavel Dudka est déjà obsolète . Veuillez utiliser la méthode mDrawerLayout.addDrawerListener() à la place pour définir un écouteur.

mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {

        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            //Called when a drawer's position changes.
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            //Called when a drawer has settled in a completely open state.
            //The drawer is interactive at this point.
            // If you have 2 drawers (left and right) you can distinguish 
            // them by using id of the drawerView. int id = drawerView.getId(); 
            // id will be your layout's id: for example R.id.left_drawer            
        }

        @Override
        public void onDrawerClosed(View drawerView) {
            // Called when a drawer has settled in a completely closed state.
        }

        @Override
        public void onDrawerStateChanged(int newState) {
            // Called when the drawer motion state changes. The new state will be one of STATE_IDLE, STATE_DRAGGING or STATE_SETTLING.
        }
    });

Marche parfaitement. À votre santé!

29
Kirill Karmazin

essayez de remplacer une méthode de DrawerLayout.DrawerListener

@Override
public void onDrawerStateChanged(int newState) {
    if( newState == DrawerLayout.STATE_DRAGGING && isDrawerOpen() == false ) {
        // this where Drawer start opening
    }
}
9
fookwood

Solution à jour:

Comme d'autres l'ont suggéré, la réponse actuelle est obsolète et il est conseillé d'utiliser mDrawerLayout.addDrawerListener(). Une solution de travail serait alors:

mDrawerLayout.addDrawerListener(new DrawerLayout.SimpleDrawerListener() {
        @Override
        public void onDrawerStateChanged(int newState) {
            if (newState == DrawerLayout.STATE_SETTLING && !mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
                // Drawer started opening
            }
        }
    });

Naturellement, remplacez GravityCompat.START par ce qui identifie votre tiroir (identifiant de la disposition ou son emplacement ~ gravité).

En outre, si vous souhaitez détecter le moment où le tiroir commence à se fermer, vous pouvez simplement effectuer les opérations suivantes:

mDrawerLayout.addDrawerListener(new DrawerLayout.SimpleDrawerListener() {
        @Override
        public void onDrawerStateChanged(int newState) {
            if (newState == DrawerLayout.STATE_SETTLING) {
                if (!mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
                    // Drawer started opening
                } else {
                    // Drawer started closing
                }
            }
        }
    });
3
NoHarmDan
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close){
      @Override
      public void onDrawerOpened(View drawerView) {
           super.onDrawerOpened(drawerView);
           app.sendScreenView("Menu");
      }
};
drawer.setDrawerListener(toggle);
toggle.syncState();

C'est le meilleur moyen.

1
Stefano Cristoni

réponse de Rookwood n'a pas fonctionné pour moi, mais une légère modification de la déclaration if a fait l'affaire)

ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, navigationDrawerLayout, topToolbar,
                R.string.open_drawer, R.string.close_drawer) {
            @Override public void onDrawerStateChanged(int newState) {
                if (newState == DrawerLayout.STATE_SETTLING && !navigationDrawerLayout.isDrawerOpen(navigationDrawerView)) {
                    // this where Drawer start opening
}
1
bastami82

Pour Kotlin

var toggle = object : ActionBarDrawerToggle(this,
                drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {

            override fun onDrawerOpened(drawerView: View) {
                super.onDrawerOpened(drawerView)
            }
        }
0
KishanSolanki124