サーバーからの通知を受け取りながら、メニュー項目のアイコンを動的に変更したい。ただし、メニュー項目のアイコンを変更するコードを実行すると、NullPointerException
が表示されます。
メニュー項目のアイコンを変更するために使用したコードは、onCreatOptionsMenu
メソッドで次のように定義されています。
@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);
}
}
updateCount
メソッドでは、次のようにアイコンを変更しています。
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);
}
}
}
}
}
});
}
これが私のmenuitem「通知」ファイルです:
<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>
これが私の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)
助けてください。
メニューが膨らんでいない(menu.getItem(index)
をチェックしている)か、存在しないindex
がある可能性があるため、mDrawerLayout != null && isDrawerOpen()
がnullを返しているようです。メニュー項目のインデックスに依存する代わりに、リソースIDを使用できます。また、nullをチェックしてください。
if (menu != null) {
MenuItem item = menu.findItem(R.id.your_menu_action);
if (item != null) {
item.setIcon(R.drawable.ic_notification1);
}
}
更新:あなたのコードに基づいて、私は以下の例を実行しました。ベースとして、またはコードが機能しない理由を見つけるために比較するために使用できます。 @layout/action_bar_notification_icon
がどのように見えるかわかりませんので、あなたの場合は問題があるかもしれません。
この例では、メニュー項目をクリックすると、ic_menu_delet
eがic_menu_edit
に置き換えられます。
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>
コード:
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()は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);
}
}
}
});
}
私も同じ問題を抱えており、invalidateOptionsMenu()
を呼び出さない限り、@ Darioの回答は魅力のように機能します。
これを解決するために、ドローアブルリソースを変数に割り当て、アイコンを変更するinvalidateOptionsMenu()
を呼び出し、onCreateOptionsMenu()
でアイコンを設定します。コードは次のようになります。
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);
}
3つのステップがあります:
MenuItem
変数を定義します。onCreateOptionsMenu
メソッドで、値(ターゲットメニュー)を割り当てます。必要に応じてアイコンを変更します。
public class NotificationActivity extends BaseActivity {
//#1
Menu globalMenuItem;
//other variables
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.notification_menu, menu);
//#2
globalMenuItem= menu.add(Menu.NONE,menuId, Menu.NONE, title);
globalMenuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS)
.setIcon(R.drawable.notification_icon_1);
//other menu items
}
//#3 call this when required
private void changeIcon(){
globalMenuItem.setIcon(R.drawable.notification_icon_2);
}
//...
}
私も同じ問題を抱えています。メニュー項目に次のものがあることを確認してください(アイコンとshowAsActionが常に設定されている):
Android:icon="@Android:drawable/ic_menu_delete"
app:showAsAction="always"