How to add a custom menu to an actionBar - android

I am working in an app with this kind of structure:
The app has no initial ActionBar so I add it on the OnCreate on each Activity this way:
android.support.v7.widget.Toolbar barra =(android.support.v7.widget.Toolbar) getLayoutInflater().inflate(local.quick_stuff.R.layout.barra_herramientas,null);
LinearLayout layout_actividad = (LinearLayout)findViewById(R.id.cp_lista_receta);
layout_actividad.addView(barra,0);
setSupportActionBar(barra);
getSupportActionBar().setTitle("Listado de Recetas");
Then I try to inflate a menu.xml to the ActionBar so the code changes to this:
android.support.v7.widget.Toolbar barra =(android.support.v7.widget.Toolbar) getLayoutInflater().inflate(local.quick_stuff.R.layout.barra_herramientas,null);
barra.inflateMenu(R.menu.menu_barra);
LinearLayout layout_actividad = (LinearLayout) findViewById(R.id.cp_lista_receta);
layout_actividad.addView(barra,0);
setSupportActionBar(barra);
getSupportActionBar().setTitle("Listado de Recetas");
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
But the result is a blank ActionBar
The Menu.xml file
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/filtro"
android:icon="#drawable/filtrado_icono"
android:title="Filtrado"
android:visible="true"
app:showAsAction="ifRoom"/>
</menu>
At the end of the day i am trying to do this to have flexibility because a want to have different menu.xml to inflate at my ActionBar.
I am thinking this could be kind of flexible but has too many branching coding.
Any help?

Just for sake of closing, and help if someone needs it:
if you call setSupportActionBar(barra);
You must override onCreateOptionsMenu() because the activity takes control of the toolbar and the Menu must be defined by that method. So I just added this to the activity code.
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_barra, menu);
return true;
}

Related

Why is action icon not showing on actionbar

I develop android application and I want to create action placed on action bar that is visible as icon. I added a drawable with resolution of 18x18px and created menu with one item, which is my action, as shown below:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".RelationsActivity">
<item
android:id="#+id/action_show_profile"
android:icon="#drawable/profile_icon_16"
android:title="#string/action_show_profile"
app:showAsAction="always" />
As you can see the showAsAction attribute is set to "always" and it is still not working. I tried with different AppThemes and nothing helped. There surely is enough space for the icon cuz action bar title is disabled:
getActionBar().setDisplayShowTitleEnabled(false);
The action is present in the overflow dropdown as if there is no space for the icon.
use this
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
And this method too
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.YOUR_MENU_FILE, menu);
return true;
}
implements AppCompatCallback
and use this code inside oncreate method
//let's create the delegate, passing the activity at both arguments (Activity, AppCompatCallback)
AppCompatDelegate delegate = AppCompatDelegate.create(this, this);
//we need to call the onCreate() of the AppCompatDelegate
delegate.onCreate(savedInstanceState);
//we use the delegate to inflate the layout
//delegate.setContentView(R.layout.activity_sync_contact);
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setNavigationIcon(R.drawable.ic_menu);// icon of navigation
toolbar.setTitle("Inbox");
delegate.setSupportActionBar(toolbar);

Changing menu items on a toolbar menu made from a xml layout

So I have this toolbar in my app, and I want to display different menu items depending on whether the user is logged in or not. When the user logs in or out I want to update my layout which for now is the toolbar menu to represent the change. For some reason though, my menu items are not removed at all, all of them are visible at all times, regardless of the login state.
My menu items:
<menu
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_add"
android:icon="#drawable/ic_action_add"
android:title="#string/action_add"
app:showAsAction="ifRoom"/>
<item
android:id="#+id/action_login"
android:icon="#drawable/ic_action_logged_out"
android:title="#string/action_log_in"
app:showAsAction="always"/>
<item
android:id="#+id/action_logout"
android:icon="#drawable/ic_action_logged_in"
android:title="#string/action_log_out"
app:showAsAction="always"/>
</menu>
The first menu item is only supposed to be visible to a user that is logged in. Also I guess it's self explanatory but I only want one of the log in/out buttons to be visible depending on the login state.
My Java code:
protected void initializeToolbar(){
myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
menu = myToolbar.getMenu();
resetToolbarMenu();
myToolbar.setOnMenuItemClickListener(this);
}
private void resetToolbarMenu(){
menu.clear();
getMenuInflater().inflate(R.menu.menu, menu);
if(loginPrefs.getBoolean("login", false)) { //loginPrefs is reference to a SharedPreference object
menu.removeItem(1);
} else {
menu.removeItem(2);
menu.removeItem(0);
}
}
Reason I got two methods is that I only want to set up the toolbar and listener once, but I want to be able to change the menu every time the user logs in/out without reloading the page.
After a successful login the resetToolbarMenu() method will be called again.
I suppose the menu.remove(0) does not update the UI, but I could not find another way to reach my menu object without first inflating it and then getting it from the toolbar, and I assume the inflation is what decides what items are visible. Basically, I could not find a way to remove any menu items before inflating or updating the UI in another way than inflating.
Solution:
I changed my java code into something like this:
protected void initializeToolbar(){
myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu); // Don't know if this is necessary or if returning true is prefered.
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(loginPrefs.getBoolean("login", false)) {
menu.getItem(0).setVisible(true);
menu.getItem(1).setVisible(false);
menu.getItem(2).setVisible(true);
} else {
menu.getItem(0).setVisible(false);
menu.getItem(1).setVisible(true);
menu.getItem(2).setVisible(false);
}
return true;
}
I also had to call invalidateOptionsMenu() on logout/login to update the toolbar/menu. However onPrepareOptionsMenu() is also automatically called whenever you open the menu for items that aren't shown on the toolbar itself.
PS: OnCreateOptionsMenu and OnPrepareOptionsMenu will not be used unless you remember to setSupportActionBar(myToolbar) as I forgot.
You can create options menu by overriding onCreateOptionsMenu. You can create 2 xml and inflate either one of them depending on your logic. To force a redraw of the menu, you can call invalidateOptionsMenu.
For example
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
if (login) {
inflater.inflate(R.menu.login_menu, menu);
} else {
inflater.inflate(R.menu.logout_menu, menu);
}
return true;
}
And outside change the flag and force redraw
login = false; // or true
invalidateOptionsMenu();
You have to override onPrepareOptionsMenu in the activity to change the items in the menu.
From the documentation:
Prepare the Screen's standard options menu to be displayed. This is called right before the menu is shown, every time it is shown. You can use this method to efficiently enable/disable items or otherwise dynamically modify the contents.

Getting a reference of ActionBar's action icon

I want to animate a ic_action_refresh in the ActionBar. I'm using AppCompat, and so far I have done this:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main,menu);
MenuItem item = menu.findItem(R.id.action_refresh);
if(item != null)
refreshView = MenuItemCompat.getActionView(item);
super.onCreateOptionsMenu(menu, inflater);
}
The results are: item is ok, but refreshView is null.
Any idea of what can I do, or what am I missing?
Edit
<item android:id="#+id/action_refresh"
android:title="#string/action_refresh"
android:icon="#drawable/ic_action_refresh"
android:orderInCategory="100"
app:showAsAction="ifRoom" />
To display an animation (I'll assume a spinning ProgressBar) in a menu item use the following:
item.setActionView(new ProgressBar(YOUR APP CONTEXT));
and when you want to get rid of the progress bar simply do item.setActionView(null);
You have to use ..
item.getActionView() // to get the current action view set for the item
but make sure you have already set action view for this item using..
item.setActionView(view)

ActionBarsharlock: from submenu move from menu to another activity

I am using ActionBarSharlock in my Application for Action Bar. In actionBar I take a button and If I click the button I see a menu with three items. Here is the code-
public boolean onCreateOptionsMenu(Menu menu) {
SubMenu subMenu1 = menu.addSubMenu("Action Item");
subMenu1.add("Sample");
subMenu1.add("Menu");
subMenu1.add("Items");
MenuItem subMenu1Item = subMenu1.getItem();
subMenu1Item.setIcon(R.drawable.sub_menu_icon);
subMenu1Item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
return super.onCreateOptionsMenu(menu);
}
But I don't know how to make this three submenu1 item clickable and move one activity to another. What kind of function I need to write. Let me know It will be great help
First: why don't you add your menu items in the XML menu file in res/menu/your_file.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"/>
<item android:id="#+id/action_compose"
android:icon="#drawable/ic_action_compose"
android:title="#string/action_compose" />
then inflate the menu in your activity:
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
and then override the onOptionsItemSelected method to handle the menu item clicks.
Also Google developed their own library for ActionBar on API level < 11 so you should try using that one as well instead of Sherlock.
Hope this helps. Best of luck.

findViewById for MenuItem returns null

This is my xml file for the ActionBar menu.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/fav_button"
android:title="Favourite"
android:icon="#drawable/unstar"
android:showAsAction="always|withText" />
</menu>
In my onCreate function, after calling setContentView. I do favButton = (MenuItem) this.findViewById(R.id.fav_button); But this returns null.
But returns the proper object on the onOptionsItemSelected function.
I'm using ActionBarSherlock, if that would make a difference.
I have tried various options suggested by other findViewById returns null questions, but they haven't solved my issue.
Instead of
favButton = (MenuItem) this.findViewById(R.id.fav_button);
in onCreateOptionsMenu after getMenuInflater().inflate(R.menu.activity_main, menu);
favButton = menu.findItem(R.id.fav_button);
Use menu.findItem() to get the menu. But this needs to be done after the menu is inflated.
Also, to answer your q in comment, you could use onPrepareOptionsMenu to set the state of your menu. If this menu is a one time updating, you could use onCreateOptionsMenu too, which is called only once.
but if someone really needs View and not MenuItem (for different manipulations, for example to start animation) you can still get it the next way:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.your_menu_xml_file, menu);
...
new Handler().post(new Runnable() {
#Override
public void run() {
view = findViewById(R.id.menu_refresh_button);
// view.startAnimation(animation);
}
});
return true;
}
Try
final Toolbar toolbar = findViewById(R.id.toolbar);
Menu menu=toolbar.getMenu();
MenuItem item = menu.findItem(R.id.'name id item');
for me works.
I don't know why, but in my case, I use findViewById(R.id.menu_id) return null. But I find that I use findViewById(item.getItemId) in onOptionsItemSelected, it return the view what we want.

Categories

Resources