I am trying to add an options menu to my Android project. The option menu displays just fine, but when the only option is clicked it fails. Debugging hasn't helped me (I haven't been developing android very long).
The XML that draws the menu item is:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/add_server"
android:icon="#drawable/plus"
android:title="#string/add_server"
android:showAsAction="never"
/>
</menu>
The code that calls the method when said option is clicked is:
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.add_server:
addNewServer();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
The method is:
public void addNewServer() {
Intent intent = new Intent(AndNetQCheckDemo.this, AddServer.class);
AndNetQCheckDemo.this.startActivity(intent);
}
When I click the button, it highlights and then fails. The debugger makes it to the .this.startActivity line then fails with an instrumentation error which I don't understand.
The device I'm using is a Samsung Galaxy S3 running 4.0.4.
Related
My app for that moment has 3 buttons, which allow for switches LED and read data from humidity sensor by bluetooth (each one sends another command to arduino e.g. '0' - LED OFF, '1' - LED ON, '2' - READ DATA).
Today I wanted add sending any messages to arduino, so I insert EditTextBox to my layout and I decided that the button to send message to Arduino from this EditTextBox will be on the action bar with this icon send icon
menu -> main.xml
`<!-- language: lang-xml -->
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_send"
android:icon="#drawable/ic_send_black_48dp"
android:title="#string/action_send" // this string is empty ' '
android:orderInCategory="1"
app:showAsAction="always" />
<item
android:id="#+id/action_settings"
android:orderInCategory="2"
android:title="#string/action_settings"
app:showAsAction="never" />
</menu>`
MainActivity.java
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// COMPLETED (9) Within onCreateOptionsMenu, use getMenuInflater().inflate to inflate the menu
getMenuInflater().inflate(R.menu.main, menu);
// COMPLETED (10) Return true to display your menu
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
Context context = MainActivity.this;
String textToShow = "...";
Toast.makeText(context, textToShow, Toast.LENGTH_SHORT).show();
return true;
case R.id.action_send:
mConnectedThread.write(txtBluetooth.getText().toString());
return true;
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
How can you see, I set app:showAsAction="always" /> and despite this send icon missing on action bar and is sent to the overflow menu, as in the picture: app
So, how can i prevent this and make that send icon will appear on action bar no in overflow menu?
I have a basic android application and have added an item to my settings menu to provide users a link to my app on the play store so that they can rate it easily.
I have got code that works on all my devices (Samsung Galaxy S3, Google Nexus 7 (2012), HTC One), however a friends Samsung Galaxy S2 does nothing when the settings item is clicked.
See code below, thanks in advance.
MainActivity.java
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.settings, menu);
return true;
}
public boolean rateApp (MenuItem item) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=manning.luke.glutenfreeingredients"));
startActivity(browserIntent);
return false;
}
Settings.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:title="#string/rateApp"
android:onClick="rateApp" >
</item>
</menu>
From the Menu Resource guide, android:onClick was only added in API Level 11 (Honeycomb) - older versions of Android will ignore this attribute.
Typically, you instead have a menu definition like:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/rateApp"
android:title="#string/rateApp">
</item>
</menu>
And then use onOptionsItemSelected(MenuItem):
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.rateApp:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(
"market://details?id=manning.luke.glutenfreeingredients"));
startActivity(browserIntent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
When I'm on Android App and i click on menu button at mobile device, settings menu appear. How i can add new item Facebook like at this setting menu ?
Maybe this is what you are looking for?
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/like"
android:title="#string/menu_facebook_like"
android:icon="#drawable/ic_menu_like"
android:showAsAction="ifRoom" />
</menu>
Then on your code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle menu item selection
switch (item.getItemId()) {
case android.R.id.like:
// Do what you want when "like" is pressed
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Of course you have to find a "like" icon (ask to Google) and resize it for the ActionBar/Menu.
I see the following misfeature on Android 4.0.4, HTC T-Mobile:
My program changes the options menu at run-time (namely, things like replacing a "Start" button with a "Stop" button). Unfortunately, the overflow menu disappears, and at least one menu item is "lost". On the first sight, it looks like the "More" menu item is replaced by another menu item, "Settings" in my case.
This does not happen on Android 2.
(I found a workaround and am posting this in case somebody else encounters this problem)
The workaround is not to let the number of visible items to decrease. It looks like Android 4 removes the "More" item when it's not needed but cannot add it when it is needed again.
I have changed my code from
private void doPrepareOptionsMenu(Menu menu) {
boolean running = ...;
menu.findItem(R.id.menu_stop).setVisible(running);
menu.findItem(R.id.menu_start).setVisible(!running);
}
to
private void doPrepareOptionsMenu(Menu menu) {
boolean running = ...;
if (running) {
menu.findItem(R.id.menu_stop).setVisible(running);
menu.findItem(R.id.menu_start).setVisible(!running);
} else {
menu.findItem(R.id.menu_start).setVisible(!running);
menu.findItem(R.id.menu_stop).setVisible(running);
}
}
and the problem disappeared. The difference is that we first make an item visible and only then make another item invisible.
In case you never changed the Android 2 menu at run-time, some context how it works:
SomeListener someListener = new SomeListener() {
public void someStateChanged() {
// This runs NOT on the UI thread
runOnUiThread(new Runnable() {
public void run() {
updateUI();
}
});
}
}
and updateUI() finally calls the code
Menu menu = weakRefOptionsMenu.get();
if (null != menu) {
doPrepareOptionsMenu(menu);
}
and, of course, onPrepareOptionsMenu() also calls doPrepareOptionsMenu():
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
doPrepareOptionsMenu(menu);
return true;
}
Related to the original issue is a case where you have a single menu item that by default is invisible. If you plan on making this item visible at runtime based on some logic, it will not appear on 4.0.4 devices. The fix is to include a disabled, empty-titled, visible item:
<item
android:title=""
android:visible="true"
android:enabled="false"
android:showAsAction="ifRoom"/>
<item
android:id="#+id/my_item"
android:title="My Item"
android:visible="false"
android:showAsAction="ifRoom"/>
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;
}