Reputation: 10224
It seems to me that one thing is missing from the DrawerLayout
implementation: and event that fires before the drawer opens.
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
public void onDrawerClosed(View view) {
//...
}
public void onBeforeDrawerOpened(View drawerView) {
//...
}
public void onDrawerOpened(View drawerView) {
//...
}
};
The reason for needing it would be to set up the status of the drawer items like menu items selected, enabled and similar. Putting this into the onDrawerOpened()
callback kinda works but it doesn't look really right to change the menu appearance after it opens.
My first thought would be to extend ActionBarDrawerToggle
and provide the new event. Shall I re-invent the wheel :-) or has this already been done by somebody?
Upvotes: 5
Views: 4008
Reputation: 17576
The setDrawerListener method recommended in the accepted answer is now deprecated. The new way to do this is to use the addDrawerListener method.
In Kotlin:
Initialize the DrawerLayout View
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
In your main activity, create an inner class that is a subclass of DrawerLayout.DrawerListener. The DrawerLayout class implements the DrawerListener interface. You can track the changing drawer position in onDrawerSlide and determine if the drawer is opening or closing:
inner class CustomDrawer : DrawerLayout.DrawerListener{
override fun onDrawerStateChanged(newState: Int) {
}
var last: Float = 0f
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
imm.hideSoftInputFromWindow(drawerView?.getWindowToken(), 0)
var opening: Boolean = slideOffset>last
var closing: Boolean = slideOffset<last
if(opening) {
Log.i("Drawer","opening")
Log.d("Last",last.toString())
} else if(closing) {
Log.i("Drawer","closing")
Log.d("Last",last.toString())
} else {
Log.i("Drawer","doing nothing")
Log.d("Last",last.toString())
}
}
override fun onDrawerClosed(drawerView: View) {
}
override fun onDrawerOpened(drawerView: View) {
}
}
Add your custom DrawerListener to the drawerLayout (I put it in the onCreate method)
var drawerListener = CustomDrawer()
drawerLayout.addDrawerListener(drawerListener)
Upvotes: 0
Reputation: 989
Mix of from Lenny and Fred answers for kotlin:
var toggle = object : ActionBarDrawerToggle(this,
drawer_layout, toolbar, R.string.drawer_open, R.string.drawer_close) {
override fun onDrawerStateChanged(newState: Int) {
super.onDrawerStateChanged(newState)
if(newState == DrawerLayout.STATE_SETTLING){
if(drawer_layout.isDrawerOpen(Gravity.LEFT)){
//closing
}else{
//opening
}
}
}
}
drawer_layout.addDrawerListener(toggle)
toggle.syncState()
Upvotes: 0
Reputation: 3421
This link can help you to solve your problem. How to detect that the DrawerLayout started opening?
Use onDrawerStateChanged(int newState) callback
You need to listen to STATE_SETTLING states - this state is reported whenever drawer starts moving (either opens or closes). So once you see this state - check whether drawer is opened now and act accordingly:
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);
Upvotes: 8
Reputation: 5939
I found this on google when I came up against this problem and didn't find an exact answer anywhere so I decided I'd post the complete answer. Hopefully it will save someone some time.
The best solution I found was to monitor the drawer state and determine if it's opening or closing using the isDrawerOpen method. Be sure to set the gravity to match the gravity used in opening / closing your drawer.
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
// ...
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_playlist, R.string.drawer_open, R.string.drawer_close) {
public void onDrawerStateChanged(int newState) {
if(newState == DrawerLayout.STATE_DRAGGING){
if(mDrawerLayout.isDrawerOpen(Gravity.LEFT)){
//closing
}else{
//opening
}
}
}
}
Upvotes: 3