it-swarm.com.de

Wie erkennt man, dass das DrawerLayout mit dem Öffnen begann?

Ich habe also Registerkarten, die ich ausblenden möchte, wenn die Navigationsleiste startet öffnet. Der Code, den ich habe, verbirgt sie, wenn er mit dem Öffnen fertig ist, aber es ist nicht das, was ich will.

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

Folgendes habe ich ausprobiert:

  • Setzen einer onClickListener auf mDrawerLayout. onClick wird nie aufgerufen
  • Setzen einer onTouchListener auf mDrawerLayout. onTouch wird nie aufgerufen
  • Untersuchte ActionBarDrawerToggle- und DrawerLayout-Klassen. Konnte nichts wie onDrawerStartedOpening finden.
39
Oleksiy

Es gibt zwei Möglichkeiten, dies zu tun:

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

slideOffset wechselt von 0 auf 1. 1 bedeutet, dass es vollständig geöffnet ist, 0 - geschlossen. 

Wenn sich der Versatz von 0 in !0 ändert, bedeutet dies, dass der Startvorgang started gestartet wurde. So etwas wie:

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) Use onDrawerStateChanged(int newState) callback

Sie müssen sich die Zustände STATE_SETTLING anhören - dieser Status wird gemeldet, wenn sich die Schublade bewegt (öffnet oder schließt sich). Sobald Sie diesen Zustand sehen, prüfen Sie, ob die Schublade jetzt geöffnet ist, und verhalten Sie sich entsprechend:

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

Die derzeit akzeptierte Antwort von Pavel Dudka ist bereits veraltet. Verwenden Sie stattdessen die Methode mDrawerLayout.addDrawerListener(), um einen Listener festzulegen.

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

Funktioniert perfekt. Prost!

29
Kirill Karmazin

versuchen Sie, eine Methode von DrawerLayout.DrawerListener zu überschreiben

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

Aktuelle Lösung:

Wie von anderen vorgeschlagen, ist die aktuelle Antwort veraltet und es wird empfohlen, mDrawerLayout.addDrawerListener() zu verwenden. Eine funktionierende Lösung wäre dann:

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

Ersetzen Sie GravityCompat.START natürlich durch das, was Ihre Schublade identifiziert (Layout-ID oder Schwerkraftposition).

Wenn Sie feststellen möchten, wann die Schublade zu schließen beginnt, können Sie einfach Folgendes tun:

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();

Es ist der beste Weg.

1

antwort von rookwood hat bei mir nicht funktioniert, aber leichte Modifikation in der if-Anweisung hat den Trick geleistet.

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

Für 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