I'm using ActionBarDrawerToggle class to tie together the functionality of DrawerLayout and the framework ActionBar to implement the recommended design for navigation drawers.
What Android developer site says is:
Call syncState() from your Activity's onPostCreate to synchronize the indicator with the state of the linked DrawerLayout after onRestoreInstanceState has occurred.
But I'm not getting what syncState() method actually does?
Please explain it as simple as possible.
The DrawerLayout indicator is the little icon to the left of the ActionBar home icon (see picture)
ActionBarDrawerToggle.syncState is called properly offset this indicator based on whether or not the DrawerLayout is open or closed after the instance state of the DrawerLayout has been restored.
Call syncState() from your activity's onPostCreate to set the state of the indicator based on whether the drawerlayout is in open or closed state once the activity has been restored with onRestoreInstanceState.
protected void onPostCreate(Bundle savedInstanceState) {
// TODO Display the navigation drawer icon on action bar when there state has changed
super.onPostCreate(savedInstanceState);
drawerListener.syncState();
}
It is called from your Activity's onPostCreate to synchronize the indicator icon with the state of the linked DrawerLayout after onRestoreInstanceState has occurred.
for example
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
this.navDrawerToggle.syncState();
}
Related
My app is set up to have a unique toolbar for each Fragment. In one particular fragment, I want to override the Navigate Up or Back button in the toolbar to give a warning to the user to confirm their intention.
I originally asked this question here and found that by changing my original code to using setSupportActionBar to implement the toolbar, I was able to maintain my unique toolbar for the fragment and ovveride the Navigate Up button.
However, I just noticed that whenever I back out of that fragment that uses setSupportActionBar for the toolbar, I get a memory leak (same as the problem found by this user). I confirmed this by commenting out the line that sets up the actionbar and saw that the leak had disappeared.
How can I maintain my unique toolbar, override the Navigate Up button and avoid this memory leak?
However, I just noticed that whenever I back out of that fragment that uses setSupportActionBar for the toolbar, I get a memory leak
You can try to eleminate this by setSupportActionBar(null) when this particular fragment is destroyed:
override fun onDestroy() {
super.onDestroy()
(requireActivity() as AppCompatActivity).setSupportActionBar(null)
}
Java:
// In the fragment
#Override
public void onDestroy() {
super.onDestroy();
((AppCompatActivity) requireActivity()).setSupportActionBar(null);
}
When I use Material Drawer, as soon as a new activity starts, drawer is being displayed automatically, but I want that it starts hidden, so I have to use function drawer.closeDrawer() in the method onResume of activity, as described below:
#Override
protected void onResume() {
super.onResume();
drawer.closeDrawer();
}
Is this the correct way to hidden the drawer when activity starts or restarts, or there is a property to be set for this purpose in the drawer?
Thank you,
Alexandre Bianchi
There are different cases why the drawer may opens after the application starts.
Either you define withShowDrawerOnFirstLaunch, this should be removed or set to false, if you don't want this behavior.
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/DrawerBuilder.java#L1188
It could also be that you open the drawer via the Drawer's API. So make sure you don't call openDrawer programtically
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/Drawer.java#L125
The Drawer comes also with a method to close the drawer. Just call closeDrawer
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/Drawer.java#L134
Put this code in oncreate and it will check the drawer is open or not...if its open it will close the drawer
DrawerLayout layout = (DrawerLayout) findViewById(R.id.drawer_layout);
if (layout.isDrawerOpen(GravityCompat.START)) {
layout.closeDrawer(GravityCompat.START);
}
So, I have a BaseActivity in which I have a toolbar and I call setSupportActionBar(toolbar).
In some of my activities that extends BaseActivity, I would like to change the navigation icon (the default arrow) to another drawable. But when I call toolbar.setNavigationIcon(myDrawable) it doesn't work, it still shows the default left pointing arrow icon.
Any idea?
Thanks.
I think you can set like this
menuDrawerToggle = new ActionBarDrawerToggle(this, menuDrawer, toolbar, R.string.drawer_open, R.string.drawer_close){...}
menuDrawerToggle.syncState();
toolbar.setNavigationIcon(getResources().getDrawable(yourDrawable));
put setNavigationIcon after syncState()
In my case: I don`t use ActionBarDrawerToggle. For me helpful was:
to change order of methods calls.
From:
Toolbar toolbar = (Toolbar)getActivity().findViewById(R.id.toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
toolbar.setNavigationIcon(R.drawable.ic_chevron_left_white_24dp);
To:
Toolbar toolbar = (Toolbar)getActivity().findViewById(R.id.toolbar);
toolbar.setNavigationIcon(R.drawable.ic_chevron_left_white_24dp);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
In my case, setNavigationIcon after syncState as #Hsieh not work!
My solution is set in onPostCreate method as below.
Override this method in your activity
#Override
protected void onPostCreate(#Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mToolbar.setNavigationIcon(R.drawable.ic_menu_button);
}
I changed from the original ActionBar to the AppCompat Toolbar and setSupportActionBar(toolbar).
When I am using getSupportActionBar() and setDisplayHomeAsUpEnabled(true) for the back arrow, the click never calls onOptionsItemSelected or any other listener method.
Do I have to implement some special listener for it? Befor everything was working just fine.
EDIT:
Initialise the ActionBar:
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
mActionBar = getSupportActionBar();
mActionBar.setHomeButtonEnabled(true);
and after replacing the content with a Fragment I do this:
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
mDrawerToggle.setDrawerIndicatorEnabled(false);
mActionBar.setDisplayHomeAsUpEnabled(true);
I know this question has been answered but I found the real cause of the problem after 2 days of frustration.
Take a look at the ActionBarDrawerToggle documentation:
https://developer.android.com/reference/android/support/v7/app/ActionBarDrawerToggle.html
Notice the two constructors there. My mistake was that I was using the second constructor that was taking a toolbar as a parameter. It took me so long to notice the last line in the consturctor documentation:
"Please use ActionBarDrawerToggle(Activity, DrawerLayout, int, int) if you are setting the Toolbar as the ActionBar of your activity."
After using the first constructor onOptionsItemSelected() was called with no issues.
Don't forget to call the ActionBarDrawerToggle.onConfigurationChanged() and onOptionsItemSelected() from your activity as described in the last part here: http://developer.android.com/training/implementing-navigation/nav-drawer.html
I had to implement an OnClickListener for the DrawerToggle:
mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popStackIfNeeded();
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
mActionBar.setDisplayHomeAsUpEnabled(false);
mDrawerToggle.setDrawerIndicatorEnabled(true);
}
});
this fixed my issue.
I had several issues using the setSupportActionBar() method. It also ignores certain color themes, so you can't style the back arrow or overflow icon (don't remember which). I just did away with ActionBar integration and use the Toolbar natively. So, as an alternative, you could do that as follows.
Just include the toolbar like you would normally, in your layout, assume it's using an id of #+id/toolbar.
Then, in code:
_toolbar = (Toolbar) findViewById(R.id.toolbar);
_toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handleNavButtonPress();
}
});
_toolbar.setOnMenuItemClickListener(_menuItemClickListener);
_toolbar.inflateMenu(R.menu.message_list_menu);
Menu menu = _toolbar.getMenu();
In this case, _menuItemClickListener can almost literally be your current onOptionsItemSelected() method renamed. You just don't have to check for menu being null anymore.
To remove items from the menu, just call menu->clear(). So in my onPause, I clear the menus and onResume, I inflate them, in my fragments, and each fragment sets the click handler in onResume. You need to always clean up, because Android won't do that for you in this approach, and the toolbar will keep adding menus every time you inflate.
One last note, to make it all work, you have to disable the action bar completely and remove it from the style.
One thing that wasn't mentioned:
If you build the options menu dynamically in onCreateOptionsMenu and return null there, the up button in the action bar will not work.
Works fine if you return the Menu parameter without adding anything into it.
Tested on emulator API 19
If you've tried everything and it just doesn't work, you can implement your own click listener like so:
myNavList.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String item = myNavList.getItemAtPosition(position).toString();
Toast.makeText(this, "You selected " + item, Toast.LENGTH_SHORT).show();
}
});
In my case the setHasOptionsMenu(true); wasn't enabled on onCreateView. Hope this helps someone.
I'm trying to implement the new NavigationDrawer provided since the last Android keynote.
I got everything up and running, the navigation drawer opens and closes when pressing on the icon on the top left corner.
But now I still have the arrow icon although I replaced it with the ic_drawer from Android. Why?
Here's my code where I specified the icon:
mDrawerToggle = new ActionBarDrawerToggle(
this,
mDrawerLayout,
R.drawable.ic_drawer, //<-- This is the icon provided by Google itself
R.string.drawer_open,
R.string.drawer_close
)
But the application still runs with the standard icon of setDisplayHomeAsUpEnabled.
Any ideas?
I just got the Navigation Drawer working. I had forgotten to add following methods also provided by the developer.android.com examples:
#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);
}
I had the same problem the answer is if you are setting
getActionBar().setDisplayShowHomeEnabled(false);
then the normal up icon is shown. So try without using it