This topic can look similar to others but I haven't found any usable answer for this case.
Here is what I want : I have a TabActivity
with a menu, containing tabs without any menu. When I press the menu button, I want the only existing menu to be displayed. If I only inflate the menu, this is working fine. But if I want to change the content of the menu (change the visibility of items in the onPrepareOptionsMenu(menu)
method) or even press the items of the menu, nothing works.
For the onPrepareOptionsMenu(menu)
, the problem seems to be coming from the menu.findItem(...)
method which returns a null Object, and I have a NullPointerException
!
In onOptionsItemSelected(item)
, none of the item IDs will be recognized.
I have noticed with the debugger that the menu Context is the activity of the current tab, so I have moved the menu inside of that activity instead, but without more success.
Last thing, I was using the same menu and very similar code in a previous version of the app, using a single activity (no tabs) and I didn't encounter any problem. When I moved to the TabActivity design it was first working fine (maybe the context of the menu was my TabActivity
instead of the Activity
of the tab), but it didn't work anymore after minor changes to the Activities of the tabs (nothing related to any menu).
If you think using ActionBar
(and the support package) would fix this, I am already planning in moving to it later, but I would like to understand and fix this first.
Here is the code :
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
MenuItem connect1 = menu.findItem(R.id.connect_1);
MenuItem connect2 = menu.findItem(R.id.connect_2);
// Here I do some stuff to prepare the menu, which could be simplified
// like this :
if (device1Connected)
if (!connect1.isVisible()) // here I get the NullPointerException
connect1.setVisible(true);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle item selection
switch (item.getItemId()) {
case R.id.select_device:
// do some stuff
return true;
case R.id.connect_1:
// do some stuff
return true;
case R.id.connect_2:
// do some stuff
return true;
case R.id.disconnect:
// do some stuff
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Here is the XML file of the menu, nothing special
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/select_device"
android:icon="@drawable/icon"
android:title="@string/choose_devices"/>
<item android:id="@+id/connect_1"
android:icon="@android:drawable/ic_menu_add"
android:title="@string/connect_1" />
<item android:id="@+id/connect_2"
android:icon="@android:drawable/ic_menu_add"
android:title="@string/connect_2" />
<item android:id="@+id/disconnect"
android:icon="@android:drawable/ic_menu_close_clear_cancel"
android:title="@string/disconnect" />
</menu>
Edit : I have added the following in the onPrepareOptionsMenu(menu)
to avoid the NullPointerException. It doesn't fix the real problem but I can now see precisely what happens when I click on a MenuItem
if (connect1 == null || connect2 == null)
return super.onPrepareOptionsMenu(menu);
When I click on the first item, getItemId()
returns, for example, 2131165207, and the second item returns 2131165208 (I have checked, they are ids of Views
of the second tab !!), but the values it should return to enter the switch/case are respectively 2131165215 and 2131165216, so as I said before, I have a problem with my item ids. I made this test with the menu within the Activity
of the first tab, because the mContext
value of the menu is always an instance of the current Activity. But even though the Context AND the Activity containing the menu are the same, it still doesn't work.
So ! I have finally figured out what was wrong. It was a building/compiling error. I have been trying before refreshing the project many time, but it was not enough, I had also tried deleting the R.java
file (where are compiling the ID numbers from the XML files), but it still didn't work; and I finally remembered about the Project -> Clear...
function in Eclipse while working on another project.
And it just worked. So that was nothing there very challenging, but at least I've learnt something valuable today.