I'm using the ActionBarDrawerToggle from the v7 appcompat library in my app and have some troubles with the menu-to-arrow animation.
According to the material design guidelines the navigation drawer should overlap the toolbar and the icon animation should not be used when opening the drawer as I understand.
Why is the animation enabled by default when opening/closing the navigation drawer and how can I disable it?
Also, how can I trigger the animation on other occurences? I found this solution but it only works for Android API 11+ and its overwritten by calling setDrawerIndicatorEnabled(false) or by an expanded ActionView in the toolbar.
When you create your ActionBarDrawerToggle, do it like this to disable the animation/arrow and always show a hamburger:
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
getToolbar(), R.string.open, R.string.close) {
#Override
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
super.onDrawerSlide(drawerView, 0); // this disables the arrow # completed state
}
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, 0); // this disables the animation
}
};
I came across this problem tooday and found simple and (I belive) a proper solution:
Just don't set ActionBarDrawerToggle instance as DrawerListener for your DrawerLayout. This way ActionBarDrawerToggle will not perform animation that depends on drawer slide offset.
If you need a listener for DrawerLayout use DrawerLayout.DrawerListener.
edit:
You can also set ActionBarDrawerToggle as a listener, but than you must overide its onDrawerSlide method. e.g. like this:
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open_desc, R.string.drawer_close_desc) {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, 0);
}
};
calling super.onDrawerSlide() with 0 value instead of slideOffset, disables the animation
Add DrawerArrowStyle in your Theme like above. It does the trick ...
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
</style>
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#android:color/white</item>
</style>
Sample Activity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(
this, mDrawerLayout, mToolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close
);
mDrawerLayout.setDrawerListener(mDrawerToggle);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
mDrawerToggle.syncState();
}
I know I am super late...
Do this in the activity:
drawerToggle.setDrawerIndicatorEnabled(false);
In styles.xml theme. Do this:
<item name="android:homeAsUpIndicator">#drawable/menu_icon</item>
mDrawerToggle = new ActionBarDrawerToggle(
this,
mDrawerLayout,
mToolbar,
R.string.drawer_open,
R.string.drawer_close
) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
invalidateOptionsMenu();
syncState();
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
invalidateOptionsMenu();
syncState();
mLeftMenuFrame.bringToFront();
mRightMenuFrame.bringToFront();
}
};
mDrawerToggle.setDrawerIndicatorEnabled(true);
mDrawerLayout.setDrawerListener(mDrawerToggle);
mToolbar.inflateMenu(R.menu.menu_main);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawerToggle.syncState();
Related
I want to disable the left swipe gesture for opening the navigation drawer as its messing with my seekbar. But setting drawer to LOCK_MODE_LOCKED_CLOSED is also disabling my hamburger icon.
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerToggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(drawerToggle);
drawerToggle.syncState();
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
Can someone please tell me what am I doing wrong?
You're not doing anything wrong. They recently changed the behavior of ActionBarDrawerToggle to disable opening/closing the drawer if it's locked.
Since your Toolbar is the support ActionBar, a workaround is to remove the Toolbar argument from the ActionBarDrawerToggle constructor call. This will cause the Activity's onOptionsItemSelected() method to be called upon clicking the toggle, and there you can check the MenuItem's item ID, and unlock the drawer before calling the toggle's method.
The ActionBarDrawerToggle class works a little differently with an ActionBar than a Toolbar, so you'll need to add the following call to show the toggle.
getSupportActionBar.setDisplayHomeAsUpEnabled(true);
Then change your ActionBarDrawerToggle constructor call as follows:
drawerToggle = new ActionBarDrawerToggle(this,
drawer,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close) {
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
};
And override the Activity's onOptionsItemSelected() method like so:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == android.R.id.home) {
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
drawerToggle.onOptionsItemSelected(item);
return true;
}
...
return super.onOptionsItemSelected(item);
}
style.xml
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
<item name="android:homeAsUpIndicator">#drawable/ic_back</item>
<item name="homeAsUpIndicator">#drawable/ic_back</item>
</style>
MainActivity.java
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP);
actionBar.setIcon(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
View actionBarView = inflator.inflate(R.layout.custom_title, null);
actionBar.setCustomView(actionBarView);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_action_nav_menu, //nav menu toggle icon
R.string.app_name, // nav drawer open - description for accessibility
R.string.app_name // nav drawer close - description for accessibility
) {
public void onDrawerClosed(View view) {
tvTitle.setText(mTitle);
//getActionBar().setTitle(mTitle);
// calling onPrepareOptionsMenu() to show action bar icons
invalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
tvTitle.setText(mDrawerTitle);
//getActionBar().setTitle(mDrawerTitle);
// calling onPrepareOptionsMenu() to hide action bar icons
invalidateOptionsMenu();
}
};
you can see in above image, where in black circle i want to show 3 line image rather than back symbol image.
Use android.support.v7 instead of android.support.v4 as following:
import android.support.v7.app.ActionBarDrawerToggle;
And change your mDrawerToggle to the following:
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.string.app_name, // nav drawer open - description for accessibility
R.string.app_name // nav drawer close - description for accessibility
)...
Add following codes:
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
change package import android.support.v4.app.ActionBarDrawerToggle; to
import android.support.v7.app.ActionBarDrawerToggle;
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.app_name, R.string.app_ );
mDrawerlayout is object DrawerLayout
I'm trying to change my action bar's home as up indicator. Right now it shows an arrow (when opened) and 3 stripes (when closed):
I want to replace this arrow with a custom drawable. The code below doesn't works:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setLogo(getResources().getDrawable(R.drawable.actionbar_logo));
getSupportActionBar().setDisplayUseLogoEnabled(true);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.string.app_name, /* "open drawer" description for accessibility */
R.string.app_name /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
//getActionBar().setTitle(mTitle);
//invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
//getActionBar().setTitle(mDrawerTitle);
//invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerToggle.setHomeAsUpIndicator(getResources().getDrawable(R.drawable.actionbar_logo));
mDrawerLayout.setDrawerListener(mDrawerToggle);
If I use <item name="displayOptions">useLogo|showHome|showTitle</item> at the style, it shows my custom drawable besides the original homeAsUpIndicator, while what I want is to replace it
How can I achieve this? Thanks!
I've been working on upgrading my app for Android API 21, and have gotten it mostly working with support library v7. However, because of these changes, the Navigation Drawer Indicator (hamburger menu button) no longer gets displayed.
It used to be that the indicator icon was set in the ActionBarDrawerToggle() method, but this is no longer the case in support lib v7.
There is another version of ActionBarDrawerToggle() that takes a ToolBar object. Do I have to have a Toolbar in addition to my Actionbar to bring back the Drawer Indicator?
What else would do the trick?
Here's my actionbar code.
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
// R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerToggle.setDrawerIndicatorEnabled(true);
mDrawerLayout.setDrawerListener(mDrawerToggle);
Just a shot in the dark here, but it might be a theme-related problem.
Does your app theme have the following items?
<style name="YourAppStyleName" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Other items ommited -->
<item name="drawerArrowStyle">#style/YourAppStyleName.DrawerArrowToggle</item>
</style>
<style name="YourAppStyleName.DrawerArrowToggle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#android:color/white</item>
</style>
That also provides a good-looking animated arrow.
Yes you have to use toolbar
mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
setSupportActionBar(mToolbar); getSupportActionBar().setDisplayShowHomeEnabled(true);
mNavigationDrawerFragment = (NavigationDrawerFragment) getFragmentManager().findFragmentById(R.id.fragment_drawer);
mNavigationDrawerFragment.setup(R.id.fragment_drawer, (DrawerLayout) findViewById(R.id.drawer), mToolbar);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close) { ... }
Okay, I double checked R.drawable.ic_drawer a few times. It is an icon with 3 bars, but my android display a left arrow. Anyone know what's wrong and how to fix it? Thanks in advance.
try to remove getActionBar().setDisplayHomeAsUpEnabled(true);
Call syncState() from your Activity's onPostCreate to synchronize the indicator with the state of the linked DrawerLayout.
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
Additionally onConfigurationChanged should be called on the ActionBarDrawerToggle, include this in your Activity:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
In your NavigationDrawerfragment class go to setUp method and do something like this with actionbar to set actionBar.setHomeAsUpIndicator() to ic_drawer just like below. It will remove back button and replace with ic_drawer button
public void setUp(int fragmentId, DrawerLayout drawerLayout) {
mFragmentContainerView = getActivity().findViewById(fragmentId);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_drawer);
}