I want to change the menu item's icon dynamically as I get notification from a server. However, I'm getting a NullPointerException
when the codes to change the menu item's icon run.
Codes I used to change the menu item's icon are defined in the onCreatOptionsMenu
method as follow:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// getMenuInflater().inflate(R.menu.main, menu);
this.menu = menu;
if (mDrawerLayout != null && isDrawerOpen())
showGlobalContextActionBar();
MenuInflater menuInflater = this.getMenuInflater();
menuInflater.inflate(R.menu.notification, menu);
return super.onCreateOptionsMenu(menu);
}
}
and in the updateCount
method, I am changing the icon as follow:
public void updateCount(int count) {
hot_count = count;
System.out.println("Value of count: " + count);
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if (hot_count > 0) {
if(hot_count>0)
{
if (menu != null) {
MenuItem item = menu.findItem(R.id.menu_hotlist);
if (item != null) {
item.setIcon(R.drawable.ic_notification1);
}
}
}
}
}
});
}
Here is my menuitem "notification" file:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
>
<item android:id="@+id/menu_hotlist"
android:actionLayout="@layout/action_bar_notification_icon"
android:showAsAction="always"
android:icon="@drawable/ic_notification"
android:title="Notification" />
</menu>
Here's my logcat:
01-20 15:03:29.811: E/AndroidRuntime(10318): java.lang.NullPointerException
01-20 15:03:29.811: E/AndroidRuntime(10318): at com.xsinfosol.helpdesk_customer.TAB_Activity$3.run(TAB_Activity.java:294)
01-20 15:03:29.811: E/AndroidRuntime(10318): at android.os.Handler.handleCallback(Handler.java:730)
01-20 15:03:29.811: E/AndroidRuntime(10318): at android.os.Handler.dispatchMessage(Handler.java:92)
01-20 15:03:29.811: E/AndroidRuntime(10318): at android.os.Looper.loop(Looper.java:137)
01-20 15:03:29.811: E/AndroidRuntime(10318): at android.os.HandlerThread.run(HandlerThread.java:61)
01-20 15:04:04.881: I/System.out(11629)
Please help.
Android ActionBar is a menu bar that runs across the top of the activity screen in android. Android ActionBar can contain menu items which become visible when the user clicks the “menu” button. In general an ActionBar consists of the following four components: App Icon: App branding logo or icon will be displayed here.
To generate ActionBar icons, be sure to use the Asset Studio in Android Studio. To create a new Android icon set, right click on a res/drawable folder and invoke New -> Image Asset.
Right-click on the res folder and selects New -> Directory. Give the name “menu” to the new directory. Further, create a new Menu Resource File by right click on the menu directory. As the ActionBar is being created for the main Activity, type the name as “main” to the Menu Resource File.
Looks like menu.getItem(index)
is returning null because menu was not inflated ( you have check mDrawerLayout != null && isDrawerOpen()
) or you might have index
that doesn't exists. Instead of relying on menu item index you can use resource id, also do check for null:
if (menu != null) {
MenuItem item = menu.findItem(R.id.your_menu_action);
if (item != null) {
item.setIcon(R.drawable.ic_notification1);
}
}
Update: based on you code i did example below that works. You can use it as base or for comparing to find why your code is not working. I don't know how @layout/action_bar_notification_icon
looks like so in your case might be problem there.
In this example ic_menu_delet
e is replaced by ic_menu_edit
once you click on menu item.
test_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/test_menu_item"
android:icon="@android:drawable/ic_menu_delete"
android:showAsAction="always"
android:title="Item1"/>
</menu>
Code:
private Menu menu;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
getMenuInflater().inflate(R.menu.test_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.test_menu_item:
changeIcon();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
changeIcon() simulates your updateCount()
public void changeIcon(){
runOnUiThread(new Runnable() {
@Override
public void run() {
if (menu != null) {
MenuItem item = menu.findItem(R.id.test_menu_item);
if (item != null) {
item.setIcon(android.R.drawable.ic_menu_edit);
}
}
}
});
}
I've also had the same problem and @Dario answers works like a charm as long as you don't call invalidateOptionsMenu()
To solve this, I assign the drawable resource to a variable and call invalidateOptionsMenu()
where I want to change the icon and I set the icon in onCreateOptionsMenu()
. The code should be like this:
private int drawableResourceId = R.drawable.default_menu_icon;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.test_menu, menu);
menu.findItem(R.id.change_menu_item_icon).setIcon(drawableResourceId);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.change_menu_item_icon:
drawableResourceId = R.drawable.changed_menu_icon;
invalidateOptionsMenu();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With