0

I have created an action bar item for messages and when a new message is received it should be updated. The problem is when I refresh the activity it sometimes shows the icon as a new message and sometimes it shows as no new messages. It happens randomly. It is not updating correctly. I checked How to update a menu item shown in the ActionBar?

But couldn't fix my problem. I realize the problem is onCreateOptionMenu execute while oncreate. How can I delay that ?

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.loggedmenu, menu);


    int no;

    try {
        no = Integer.parseInt(noOfmsgs);
    } catch (NumberFormatException e) {
        no = 0;
    }

    if (no > 0) {
        menu.findItem(R.id.messages)
                .setIcon(R.drawable.ic_action_new_email);
    } else {
        menu.findItem(R.id.messages).setIcon(R.drawable.ic_action_email);
    }

    return true;
}
Community
  • 1
  • 1
Dumindu Madushanka
  • 494
  • 1
  • 9
  • 19
  • 1
    How do you refresh the activity? Also how do you get `noOfmsgs` value and update it? – Blo May 10 '14 at 16:53
  • @Fllo I realize that the problem is onCreateOptionMenu execute while oncreate. How can I delay that ? because oncreate should excute to get value for noOfmsgs variable. – Dumindu Madushanka May 10 '14 at 16:56
  • 1
    @dumidu You can't delay `Activity.onCreateOptionsMenu` from being called in `Activity.onCreate`, but `Activity.invalidateOptionsMenu` will recreate the options menu and call `Activity.onCreateOptionsMenu` again. You should update your post and include how you retrieve `noOfmsgs`. – adneal May 10 '14 at 17:03
  • @adneal noOfmsgs retrive from database as a jason. It works fine. I have print it on log. – Dumindu Madushanka May 10 '14 at 17:28

1 Answers1

1

As you said, onCreateOptionsMenu is called once the Activity is created and that's all, at least that you call invalidateOptionsMenu() to get this method again. However, you can have a global variable in the activity to update your items later as follows:

// global var menu
private Menu mMenu;

// onCreate, onResume, etc.

// Init the var
@Override
public boolean onCreateOptionsMenu(Menu menu) {
     this.mMenu = menu;
     getMenuInflater().inflate(R.menu.loggedmenu, menu);
     return true;
}  

Then, after doing an AsyncTask, a Thread or whatever you do to update the noOfmsgs value, call this method:

// update the items
private void updateMenuItems() {
    int no;
    try {
        no = Integer.parseInt(noOfmsgs);
    } catch (NumberFormatException e) {
        no = 0;
    }
    if (no > 0) {
        mMenu.findItem(R.id.messages).setIcon(R.drawable.ic_action_new_email);
    } else {
        mMenu.findItem(R.id.messages).setIcon(R.drawable.ic_action_email);
    }
} 
Blo
  • 11,903
  • 5
  • 45
  • 99
  • Where do you get a NPE @dumidu? – Blo May 10 '14 at 19:10
  • @dumidu I use this behaviour for a refresh icon without problem, and you have [a same snippet code](http://stackoverflow.com/a/23123777/2668136) used to collapse an item in ActionBar, also you can find [a solution with `getItem(int)`](http://stackoverflow.com/a/19882555/2668136) on SO. I'd suggest you to check if `mMenu` or `noOfmsgs` return `null`. – Blo May 11 '14 at 02:26
  • Also, @dumidu I found another solution which works with that: [How to dynamically change menu item text outside of onOptionsItemsSelected or onCreateOptionsMenu?](http://stackoverflow.com/a/7066901/2668136) – Blo May 11 '14 at 02:36
  • item text will change. but I can not change the icon. – Dumindu Madushanka May 11 '14 at 02:54