What is safe to put in OnCreateOptionsMenu in Android Activity? - android

In my app I have a Spinner as a menu item in the action bar of my Activity. It has the collapsible action view so it appears only when the icon is clicked. I obtain a reference to my Spinner like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my_menu, menu);
spinner = (Spinner)menu.findItem(R.id.spinner).getActionView();
spinner.setAdapter(spinnerAdapter);
return true;
}
I have been reading about when OnCreateOptionsMenu is called and answers vary, with some saying it's called during onCreate. The problem is the spinnerAdapter is initialized in onCreate, and more importantly, the ArrayList containing the data for the Spinner is initialized and populated from a Room database in onCreate. So my question is, is it possible that the code from OnCreateOptionsMenu gets executed before some of the code in onCreate?

Related

Avoid recreation of programmatically created menuitem in fragment

My question is how can I prevent that my programmatically created toolbar menuItem (Menu with submenus) gets overridden with the xml layout every time the fragment resumes.
I want to create my expensive toolbar menuitem only when fragment is first time created and not when it is resumes.
I inflat my toolbar in the onCreateOptionsMenu() and store an instance of the menu item.
private MenuItem menuItem;
private SubMenu expessiveSubmenu;
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_layout, menu);
menuItem= menu.findItem(R.id.menuItem);
}
The menuItem gets populated when the async loader finishs.
#Override
public void onLoadFinished(Loader<> loader, Data data) {
//Expensive call
expensiveSubmenu= makeExpensiveSubMenu(menuItem, data);
}
Now the menu is fully populated and visible in the toolbar and I also have an instance of my submenu.
Because onCreateOptionsMenu() is called evertime the fragment is resumed my menu get's overridden with the xml layout and I have to create the expensive submenu again. A mehtod like menu.addSubmenu(Menu) would solve my needs but I couldn't find one. Any ideas would be appreciated.

Android actionbar menu item

I have a item menu (sorting list) in my actionbar that I have to set its visibility to VISIBLE / GONE (depending on the list size -> empty or not).
So what I need is to check if listview is empty or not and set the visibility of that menu item accordingly, and I managed to came up with some code to do that (check listview size in onCreateOptionsMenu and set menu item visibility), but the problem is that the list can change its content both from same activity or from another, leaving me no option (IMO) than to check again listview size and set visiblity in onResume().
Here comes next problem: setting visibility of that item in onResume(), will throw a NPE, as I don't yet have that MenuItem initialized (onCreateOptionsMenu is called after onResume).
Any ideas on how to solve this situation would be appreciated.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getSupportMenuInflater().inflate(R.menu.main, menu);
/*
* initialize sortMenuItem so it can be used for turning visibility
* on/off in onResume()
*/
sortMenuItem = menu.findItem(R.id.menu_sort);
return true;
}
#Override
public void onResume() {
super.onResume();
boolean isListEmpty = mInterviewsList.isEmpty();
Log.d(LOG_TAG, "sortMenuItem is null? " + (sortMenuItem == null));
// sortMenuItem is indeed null
sortMenuItem.setVisible(isListEmpty);
sortMenuItem.setEnabled(!isListEmpty);
this.invalidateOptionsMenu();
}
You can add sortMenuItem dynamicaly in onCreateOptionsMenu depending on your listview size and in onResume call supportInvalidateOptionsMenu() if you use (google ActionBar compat lib) or similar method.

Get item view from ActionBar

I have an ActionBarSherlock with one menu item in my bar. When I'm call
View item = findViewById(R.id.my_item);in activity's button onClick all works fine as expected.
But when I try to do this in onCreate or onResume or even in onPostResume it is always null. I also tryed do this in onCreateOptionsMenu(Menu menu) after inflating my menu from resource, but without any succes.
Therefore I can't understand when actionbar items created and how to catch this moment?
As it has been said here and here, getActionView returns the view that we sets in setActionView. Therefore, the only one way to customize action bar menu item described here
actually it is possible to get the view of the action item, even if it's not customized.
however, do note that sometimes action items get to be inside the overflow menu so you might get a null instead.
so, how can you do it?
here's a sample code:
public boolean onCreateOptionsMenu(final Menu menu) {
getSupportMenuInflater().inflate(R.menu.main, menu);
new Handler().post(new Runnable() {
#Override
public void run() {
final View syncItemView = findViewById(R.id.action_search);
...
this was tested when using actionBarSherlock library, on android 4.1.2 and android 2.3.5 .
another alternative is to use a more extensive way , used on the showcaseView library, here .
first of all get a menu reference as below:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.custom_menu, menu);
customMenu = menu;
return super.onCreateOptionsMenu(menu);
}
after that you can get the item you need as below
customMenu.getItem(0);

Android - Populate menu upon activity onCreate

Perhaps I'm missing the obvious, but my menu is only been created and populated when onCreateOptionsMenu(Menu menu) is called, as in this example, and this only seem to be called after I press the menu button.
I would like to populate the menu upon the creation of the activity, how can achieve that?
UPDATE:
Perhaps a better question would be:
How can I get the Menu instance of my Activity?
Thanks
Create a class which holds those states then set your enabled/checked etc from the properties of that class in onCreateOptionsMenu()
class MenuStates{
public static boolean userDidPressTheButton;
public static boolean serverDidRespond;
public static boolean colorWasChanged;
}
void someEventHandler(){
MenuStates.userDidPressTheButton = true;
}
void onCreateOptionsMenu(){
myCheckBox.setChecked(MenuStates.userDidPressTheButton);
}
[EDIT]
You don't say why you want to get the menu instance. One approach:
Menu optsMenu;
...
// this is called once only before the end of the Activity onCreate().
onCreateOptionsMenu(Menu menu){
opstMenu = menu;
super.onCreateOptionsMenu(menu);
}
Following that, modify your menu as you wish. Do any "as it pops" up work in onPrepareOptionsMenu().
The key understanding is the difference between onCreateOptionsMenu() and onPrepareOptionsMenu().
[MORE EDIT]
To completely control the thing yourself:
Menu optsMenu;
onCreate(){
openOptionsMenu() // the menu won't show in onCreate but onCreateOptionsMenu is shown
closeOptionsMenu()
}
onCreateOptionsMenu(Menu menu){
optsMenu = menu;
}
onPrepareOptionsMenu(Menu menu){
menu.clear();
for (int i=0;ioptsMenu.size();i++){
menu.add(optsMenu.get(i).getTitle());
}
return super.onPrepareOptionsMenu(menu);
}
From the docs
You can safely hold on to menu (and any items created from it), making modifications to it as desired, until the next time onCreateOptionsMenu() is called.
http://developer.android.com/reference/android/app/Activity.html#onCreateOptionsMenu%28android.view.Menu%29

How can I get the options menu of my Activity?

In some methods of my Activity I want to check the title of menu or know if it is checked or not. How can I get Activity's menu. I need something like this.getMenu()
Be wary of invalidateOptionsMenu(). It recreates the entire menu. This has a lot of overhead and will reset embedded components like the SearchView. It took me quite a while to track down why my SearchView would "randomly" close.
I ended up capturing the menu as posted by Dark and then call onPrepareOptionsMenu(Menu) as necessary. This met my requirement without an nasty side effects. Gotcha: Make sure to do a null check in case you call onPrepareOptionsMenu() before the menu is created. I did this as below:
private Menu mOptionsMenu;
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
mOptionsMenu = menu
...
}
private void updateOptionsMenu() {
if (mOptionsMenu != null) {
onPrepareOptionsMenu(mOptionsMenu);
}
}
Call invalidateOptionsMenu() instead of passing menu object around.
you could do it by passing the Menu object to your Activity class
public class MainActivity extends Activity
{
...
...
private Menu _menu = null;
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
_menu = menu;
return true;
}
private Menu getMenu()
{
//use it like this
return _menu;
}
}
There several callback methods that provide menu as a parameter.
You might wanna manipulate it there.
For example:
onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
onCreateOptionsMenu(Menu menu)
onCreatePanelMenu(int featureId, Menu menu)
There several more, best you take a look in activity documentation and look for your desired method:
http://developer.android.com/reference/android/app/Activity.html
As far as I could understand what you want here is which may help you:
1. Refer this tutorial over option menu.
2. Every time user presses menu button you can check it's title thru getTitle().
3. Or if you want to know the last menu item checked or selected when user has not pressed the menu button then you need to store the preferences when user presses.
Android now has the Toolbar widget which was a Menu you can set/get. Set the Toolbar in your Activity with some variation of setSupportActionBar(Toolbar) for stuff like onCreateOptionsMenu from a Fragment for example. Thread revived!

Categories

Resources