2015-01-20 15 views
8

Chcę zmienić dynamicznie ikonę elementu menu, gdy otrzymuję powiadomienie z serwera. Jednak otrzymuję kod NullPointerException, gdy działają kody zmieniające ikonę elementu menu.Jak dynamicznie zmienić ikonę elementu menu paska akcji

Kody kiedyś zmienić ikonę elementu menu są określone w metodzie onCreatOptionsMenu następująco:

@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); 
    } 
} 

iw sposobie updateCount, jestem zmieniającym ikonę następujące:

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); 
        } 
       } 
      } 
      }     
     } 
    }); 
} 

Oto mój plik "powiadomień" w moim 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> 

Oto mój 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) 

Proszę o pomoc.

Odpowiedz

9

Wygląda na to, że menu.getItem(index) zwraca wartość pustą, ponieważ menu nie było napompowane (masz sprawdzenie mDrawerLayout != null && isDrawerOpen()) lub możesz mieć index, która nie istnieje. Zamiast opierać się na wskaźniku pozycji menu można użyć identyfikatora zasobów, czy też sprawdzić wartość null:

if (menu != null) { 
    MenuItem item = menu.findItem(R.id.your_menu_action); 
    if (item != null) { 
     item.setIcon(R.drawable.ic_notification1); 
    } 
} 

Update: na podstawie kodu ciebie zrobiłem przykład poniżej, który działa. Możesz użyć go jako bazy lub porównania, aby znaleźć przyczynę, dla której Twój kod nie działa. Nie wiem, jak wygląda @layout/action_bar_notification_icon, więc w twoim przypadku może to być problem.

W tym przykładzie ic_menu_delet e zostaje zastąpione przez ic_menu_edit po kliknięciu elementu menu.

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> 

Kod:

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() symuluje 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); 
       } 
      } 
     } 
    }); 
} 
+0

Zaimplementowałam Twój kod, jednak nie zmienia on ikony. Sir prośby mówią mi, jak zmienić ikonę. –

+0

Upewnij się, że wywoływana jest funkcja item.setIcon(). Jeśli nie, sprawdź, dlaczego. – Dario

+0

menu powraca null –

0

miałem ten sam problem. Należy upewnić się, że następujące w menu (ikona i showAsAction zawsze ustawione):

android:icon="@android:drawable/ic_menu_delete" 
app:showAsAction="always" 
3

miałem również ten sam problem i @Dario odpowiada działa jak czar tak długo, jak don” t zadzwoń pod numer invalidateOptionsMenu()

Aby rozwiązać ten problem, przypisz zasób do pobrania do zmiennej i zadzwoń pod numer invalidateOptionsMenu(), gdzie chcę zmienić ikonę i ustawię ikonę w postaci onCreateOptionsMenu(). Kod powinien wyglądać następująco:

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); 
} 
0

Istnieją 3 kroki:

  1. definiują globalną MenuItem zmienną.
  2. w metodzie onCreateOptionsMenu należy przypisać do niego wartość (docelowe menu ).
  3. zmienić ikonę.

    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 
        private void changeIcon(){ 
         flashMenuItem.setIcon(R.drawable.notification_icon_2); 
        } 
        //... 
    } 
    

    Mam nadzieję, że to pomaga.