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.
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);
}
I am setting my toolbar:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_back);
toolbar.setTitle(R.string.app_name);
How can I retrieve the home button (android.R.id.home) as a MenuItem?
Here's what I tried:
MenuItem back = menu.findItem(android.R.id.home);
But that makes a NullPointerException for some reason. So how can I retrieve it as MenuItem without getting a NullPointerException?
This SO answer, suggests the following code but it doesn't seem to work and I can't find anything else.
getWindow().getDecorView().findViewById(android.R.id.home);
In any case it is hacky, because you shouldn't need that reference, and you shouldn't be traversing the view hierarchy to get it in any case. Since the Android SDK purposefully hides this from you, it is not something you should attempt to get, as even if the above code did work, it may not work in a future version (which actually seems like a possible explanation for it not working for me as I tested in SDK 23 Marshmallow).
So, if you want to set the icon, you can do it by setting the android:homeAsUpIndicator in your theme, as suggested here.
If you want to detect a click event on the home button, the correct way is by overriding the onOptionsItemSelected method of Activity, for example
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
// do something
return true;
}
return false;
}
Any other use would be outside the intended purpose and so not supported, as is agreed by others such as in this post.
I didn't find out to get it as a MenuItem, but, to disable the home button pogrammatically:
getSupportActionBar().setDisplayHomeAsUpEnabled(true/false)
This is what I needed. But I still didn't find out how to get it as a MenuItem.
I have a Navigation Drawer (appcompat v7) in my app which is working perfectly fine.
Now I want to disable it, until the user buys an in-app-purchase to unlock additional functionality. So in my Activity.onCreate(), after initializing the drawer and populating it, I am calling this function:
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
This function is not doing anything. The drawer continues to open and close as normal after tapping the drawer carat in the actionbar. I tried calling this function in Activity.onResume() without any difference.
What is the correct way to use this function?
(I tried looking online for answers, but couldn't find anything which addresses my issue). Any help is appreciated, as I am stuck on this issue for quite sometime now.
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
is only disabling the opening drawer layout by swiping till you click navigation drawer icon
keep a boolean variable
write mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); in onStart() and also write below lines of code
#Override
public boolean onOptionsItemSelected(android.view.MenuItem item) {
if(!disabled)
{
if (item.getItemId() == android.R.id.home) {
if (mDrawerLayout.isDrawerOpen(mDrawerLinearLayout)) {
mDrawerLayout.closeDrawer(mDrawerLinearLayout);
} else {
mDrawerLayout.openDrawer(mDrawerLinearLayout);
}
}
}
return super.onOptionsItemSelected(item);
}
this will work for sure
When you call setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) it locks opening and closing drawer only by swipes.
The drawer continues to open and close as normal after tapping the drawer carat in the action bar because your drawer will still respond to calls to openDrawer(int), closeDrawer(int) although a drawer is locked.
You need to add some logic in your action bar menu button listener and not to call openDrawer(int) when you don't want it to open.
Btw, it is okay to call setDrawerLockMode(int) in onŠ”reate
There is a bug with DrawerLayout and used gravity. I have reported it here:
https://issuetracker.google.com/issues/136738274
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 implemented my left slide drawer for menu options using Simple-side-drawer Library. Its working fine but the issue is, the drawer layout menu options are responding to onclick events even after my drawer is closed state ie (menu options responding to onclick events from my MainActivity).
You can check SimpleSideDrawer's isClosed() method to make sure if it is closed.
SimpleSideDrawer menuDrawerLeft = new SimpleSideDrawer( this );
menuDrawerLeft.setLeftBehindContentView(R.layout.menu_drawer_left);
final Button buttonInLeftDrawer = (Button)findViewById(R.id.buttonInLeftDrawer);
buttonInLeftDrawer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (menuDrawerLeft.isClosed()) {return;}
//runs only when the drawer is open
}
});
Without looking at your code it's hard to give any suggestions.
One advice though. Are you using this library:
https://github.com/adamrocker/simple-side-drawer
If so, please consider using the built-in Navigation Drawer that Google has released instead. It follows the design guidelines (which Simple Side Drawer does not) and is well tested to work.
See these resources for your implementation:
http://developer.android.com/design/patterns/navigation-drawer.html
http://developer.android.com/training/implementing-navigation/nav-drawer.html