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.
Related
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
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 using the ActionBarSherlock library and I'm following the exact steps as suggested here and here to enable navigation to the previous screen.
My code looks like this:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
and
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// This callback is used only when mSoloFragment == true (see
// onActivityCreated above)
switch (item.getItemId()) {
case android.R.id.home:
// App icon in Action Bar clicked; go up
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // Reuse the
// existing
// instance
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
But R.id.home is not recognized and home shows up in red. :-/ If I use the native actionbar the home declaration takes me to ids.xml file. But here the declaration is not found while I use the ActionBarSherlock Activity. Am I missing something?
just replace this
android.R.id.home
to
R.id.home
and check your code... run it
because
R.layout.* are layouts you provide (in res/layout, for example).
android.R.layout.* are layouts that ship with the Android SDK.
I know this is an old question but I believe the right answer is missing.
It should be be android.R.id.home because it is a platform resource, so your code is fine.
Make sure your minSdkVersion is 11 or higher since home was introduced in 11.
I remeber running into this problem and apparently its quite frequent a quick google or search through stack overflow should've given you some insight anyways check this thread out R cannot be resolved - Android error
Im pretty sure your running into same problem
When first experimenting with the SlidingMenu library by jfeinstein10, in the example project, clicking the icon button in the action bar would cause the sliding menu to open and then close when clicked again. After implementing ActionBarSherlock and getting it to run (not throwing any errors), the icon no longer causes the menu to appear. So far I have changed the SlidingMenu library to extend SherlockActivity instead of extending android Activity as suggested in the SlidingMenu read me. I have also changed the following lines in BaseActivity:
Original:
// customize the ActionBar
if (Build.VERSION.SDK_INT >= 11) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
Changed to:
// customize the ActionBar
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
It seems as if the button press is being registered in LogCat, but it's not doing anything.
I've been trying to figure this out for a while now and just wanted to see if anyone has experienced this issue or is familiar enough with both/either libraries to quickly help pinpoint where I'm going wrong or what I forgot to do.
Thanks!
this is your problem
import android.view.MenuItem
you must use Shearlock Menu not android Menu.
remove android MenuItem import and use Shearlock one`s
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Menu;
I hit this problem as well, and was already importing the actionbarsherlock menu and menuitem libraries.
What did the trick for me was adding the following to the onOptionsItemSelected function so the relevant toggle function was called when the home button action was triggered...
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId())
{
case android.R.id.home:
getSlidingMenu().toggle();
return true;
...
}
return super.onOptionsItemSelected(item);
}
I have an Options menu up and running in my Android application and I've overridden the onCreateOptionsMenu, onOptionsItemSelected and onPrepareOptionsMenu methods to customize the menu a little.
My question is related to keeping the Options menu open after the user clicks on a menu item. Basically, I'd like to be able to hide the menu until the user clicks on the device menu key. Once the user clicks on this key, I'd like to be able to hold the menu in place regardless of how many times the user clicks on menu items. If the user wants to hide the Options menu, they'd just need to click on the device menu key again.
Is this type of interaction supported (or even advisable). If this interaction is not supported, any alternative suggestions are more than welcome.
Cheers!
Sean
This will not be possible with onCreateOptionsMenu and the other methods. They always act that way.
But you can do it another way. But there you have to program the whole menu yourself. Basically add the Menu in your layout.xml and let it be hidden (visibility = gone). Then you overwrite the methods onKeyDown. There you check if it is the Menu key. if the menu is not yet open yes, then you show the menu. If it is open already, you hide it.
should not be too difficult. Good thing as well is, that you can make the menu look exactly the way you want and as well let it react the way you want.
For anybody like me, who found this question in google:
To keep menu open after selecting item, you need this code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
item.setChecked(!item.isChecked());
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
item.setActionView(new View(this));
item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
return false;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
return false;
}
});
return false;
}
Important to return false in onOptionsItemSelected and methods of OnActionExpandListener
This solution from #MayurGajra. More details here: How to hold the overflow menu after I click it?