I've developed an application which contains a menu icon in my actionbar, I create the menu as below:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
and here's the code for the onOptionsItemSelected:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_home:
startActivity(new Intent(this, MainActivity.class));
return true;
case R.id.menu_adv_search:
startActivity(new Intent(this, AdvSearchActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
using my smart phone the menu icon is there (using LG phone), but when I test it on my tablet (Galaxy Tab 8) the menu icon is gone, but the functionality is still there. pressing the menu soft button at the bottom, the popup appears, but the icon is missing from the top action bar. How to fix it? any ideas?
On devices with hardware menu buttons ( for example Galaxy series of samsung) the overflow menu behaves as the 'traditional' menu, by using the hardware menu button.
please use following attribute for each of your menu item
android:showAsAction="always"
if you are using actionbarcompat pack , then instead of above attribute use following
app:showAsAction="always"
don't forget to add the following namespace aswell
xmlns:app="http://schemas.android.com/apk/res-auto"
As I found out, on devices with menu button hardware provided, the menu icon will be hidden and making the menu item showAsAction="always" will not bring the menu icon back it in my question I was intending to, so I've found the solution Here
and here's the code I've used from the above link to overcome this issue(if it can be called an issue):
private void getOverflowMenu() {
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if(menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
you can just put this function in your activity or base activity and call it in your onCreate function and it will do all the magic for ya.
Related
I am having trouble getting the menu icon to show up on the action bar. I tried setting
android:showAsAction="always"
but even that doesn't work. In an earlier project I just used
android:showAsAction="ifRoom|withText"
and that worked. The only thing different with this project is that I am building with gradle instead of ANT. Could that make a difference?
Here is my menu xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/new_transaction"
android:icon="#drawable/ic_menu_add"
android:title="#string/new_transaction"
android:titleCondensed="#string/new_transaction_condensed"
android:showAsAction="always" />
</menu>
I copied each version of ic_menu_add.png from the android library to each respective drawable folder.
And here is my onCreateOptionsMenu in my ActionBarActivity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.account_pager, menu);
return true;
}
No matter what I try, the icon does not show up. I've tried changing the max and min API level, but to no avail. In order to click the menu item, I have to go to the overflow menu and then click the dropdown menu item there, which is definitely less than ideal. How can I make the icon show?
My min API level is 11, and my max is 20. I am developing on an HTC One running Android 4.1.2, if any of that matters.
Thanks in advance.
Try this:
#Override
public boolean onMenuOpened(int featureId, Menu menu) {
if (featureId == Window.FEATURE_ACTION_BAR && menu != null) {
if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
try {
Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
} catch (NoSuchMethodException e) {
Log.e("", "onMenuOpened", e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
return super.onMenuOpened(featureId, menu);
}
I am trying to present a custom action bar while long pressing a textview. My menu has more than 5 items which causes some of the items to be present under the overflow menu.
When I press the overflow icon, the action bar gets destroyed and I am not able to choose any item inside the overflow.
ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.add_rule_menu, menu);
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
for (int i = 0; i < menu.size(); i++) {
MenuItem item = menu.getItem(i);
if (!mOptionsList.contains(item.getItemId()))
item.setVisible(false);
}
return false;
}
// Clicking on overflow button does not trigger this method at all.
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
// Rest of the code
}
}
public void onDestroyActionMode(ActionMode mode) {}
};
textView.setCustomSelectionActionModeCallback(mActionModeCallback);
I filed an issue about this years ago, which has never been resolved.
A cheesy workaround is to use nested action modes. By this, I mean you have an item in an action mode that finishes the current mode and starts a new one, to provide a "drill-down menu" effect. I use this in my recently-resuscitated RichEditText widget, which offers an action mode for formatting text. I add a "format" item to the default action mode via setCustomSelectionActionModeCallback(). Tapping on "format" opens another action mode that offers options like bold and italic, along with further drill-downs to get to thinks like font changes.
I have a samsung galaxy tab3 and I have the menu implemented in the usual manner - i.e.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.game_menu, menu);
return true;
}
and for menu selected
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.new_game:
newGame();
return true;
case R.id.help:
showHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
In my xml ive used android:showAsAction="never" for items that I want to see in overflow and android:showAsAction="ifRoom" for items I want to see upfront. But in this tablet I see only the ones with ifRoom set and the others just disappear and the menu button does not show the overflow items. I've looked at all answers on SO and tried the popular ones like setting minimum and target sdk versions to less than 11 and so on. But the menu just wont come up. It works fine in devices that dont have the capacitive menu touch and an overflow button is shown in the action bar.
Well it ended up working when I programmatically called openOptionsMenu with onKeyDown
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
openOptionsMenu();
}
return true;
};
MAybe you have a theme (like full screen) that does not support an ActionBar?
I am looking for a way to have the options menu persist on screen as soon as the activity is opened without pressing the menu button of the simulator and it should be there until one of the options in the menu is pressed
Currently I have made an option menu like this:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/icon"
android:icon="#drawable/icon" />
<item android:id="#+id/text"
android:title="Text" />
<item android:id="#+id/icontext"
android:title="Icon and text"
android:icon="#drawable/icon" />
</menu>
And my code is:
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId())
{
case R.id.icon:
break;
case R.id.text:
break;
case R.id.icontext:
break;
}
return true;
}
Please suggest changes in my code.
Activity‘s option menu can be programatically opened and closed with the openOptionsMenu and closeOptionsMenu respectively
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
openOptionsMenu();
}
and to close:
closeOptionsMenu();
for lvls that do not support onAttachedToWindow could be used delayed execution(Not the best way):
new Handler().postDelayed(new Runnable() {
public void run() {
openOptionsMenu();
}
}, 1000);
I haven't tried this one, but you could look at openOptionsMenu.
Then after it's open you should try to intercept the menu button press and the back button press (as you would close the menu otherwise) and only disable this once one of the option items has been selected.
With this said, this all looks like a hack, so maybe you should consider a different solution for what you want to achieve.
so I am trying to get my menu item, that is show on the action bar to behave like a checkable menu option. The firs part works, meaning it is checkable and when I press it, and set in code the setChecked(true) it works. But what does not work is the visual part. There is no change in how a menu item looks on the action bar in checked and unchecked states? I tried using invalidateOptionsMenu() but that does not do the job, and not only that, with that line in my code I can't get out of the checked state?!?
What happens is that invalidate OptionsMenu() seams to unset the checked state and I end up 'looping', or on every press of that menu item I keep going to the unchecked part of the code where it gets checked and with invalidate it gets unchecked I guess...
Here is the code from my XML file for menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/lenslist_menu_add"
android:showAsAction="always"
android:title="#string/add"/>
<item android:id="#+id/lenslist_menu_delete"
android:showAsAction="always"
android:checkable="true"
android:title="#string/delete"/>
</menu>
And here is the java code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.lenslist_menu_add:
return true;
case R.id.lenslist_menu_delete:
if (item.isChecked() == true) {
item.setChecked(false);
deleteMode = false;
lensAdapter.setDeleteMode(false);
} else {
item.setChecked(true);
deleteMode = true;
lensAdapter.setDeleteMode(true);
}
lensAdapter.notifyDataSetChanged();
return true;
}
return super.onOptionsItemSelected(item);
}
Thanks!
Checkable items appear only in submenus or context menus.
You are using them as main menu items, hence it will not work.
SOURCE: Download the API DEMOS, and open the file ApiDemos/res/menu/checkable.xml, you'll see it as a comment on line 13. I don't know why they don't mention this in the Developer Documentation
reference with comment.:
http://alvinalexander.com/java/jwarehouse/android-examples/platforms/android-2/samples/ApiDemos/res/menu/checkable.xml.shtml
Or just do it yourself
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.item1).setIcon(menu_checked?R.drawable.menu_ico_checked:R.drawable.menu_ico_unchecked);
return super.onPrepareOptionsMenu(menu);
}
and in onOptionsItemSelected do:
....
menu_checked=!menu_checked;
invalidateOptionsMenu();
The best solution is to set the actionLayout of the <Item> to a CheckBox. This solution gives you a native-looking checkbox (with material animations etc), with a font that matches the other items, and it works both as an action and in the submenu.
Create a new layout called action_checkbox.html:
<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:checked="false"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Menu"
android:id="#+id/action_item_checkbox"
/>
Set your <Item> like this. Note that you need the Checkable and Checked still in case it is shown in a sub-menu (in which case the actionLayout is ignored.
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
<item android:id="#+id/menu_action_logging"
android:title="#string/action_logging"
android:orderInCategory="100"
android:showAsAction="always"
android:checkable="true"
android:checked="false"
android:actionLayout="#layout/action_checkbox"
/>
</menu>
In your code, when the menu is created we need to a) set the title of the checkbox to match the menu item title, b) restore the checked state of both the menu checkable, and our extra checkbox, and c) add an onClicked() listener for our extra checkbox. In this code I am persisting the state of the checkbox in a RetainedFragment.
// Set the check state of an actionbar item that has its actionLayout set to a layout
// containing a checkbox with the ID action_item_checkbox.
private void setActionBarCheckboxChecked(MenuItem it, boolean checked)
{
if (it == null)
return;
it.setChecked(checked);
// Since it is shown as an action, and not in the sub-menu we have to manually set the icon too.
CheckBox cb = (CheckBox)it.getActionView().findViewById(R.id.action_item_checkbox);
if (cb != null)
cb.setChecked(checked);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
inflater.inflate(R.menu.menu_main, menu);
super.onCreateOptionsMenu(menu, inflater);
// Restore the check state e.g. if the device has been rotated.
final MenuItem logItem = menu.findItem(R.id.menu_action_logging);
setActionBarCheckboxChecked(logItem, mRetainedFragment.getLoggingEnabled());
CheckBox cb = (CheckBox)logItem.getActionView().findViewById(R.id.action_item_checkbox);
if (cb != null)
{
// Set the text to match the item.
cb.setText(logItem.getTitle());
// Add the onClickListener because the CheckBox doesn't automatically trigger onOptionsItemSelected.
cb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onOptionsItemSelected(logItem);
}
});
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_action_logging:
// Toggle the checkbox.
setActionBarCheckboxChecked(item, !item.isChecked());
// Do whatever you want to do when the checkbox is changed.
mRetainedFragment.setLoggingEnabled(item.isChecked());
return true;
default:
break;
}
return false;
}