I can easily do it when I am using onCreateOptionsMenu or onOptionsItemSelected methods.
But I have a button somewhere in screen, and on clicking that button, it should enable/disable context menu items.
Anyway, the documentation covers all the things.
Changing menu items at runtime
Once the activity is created, the
onCreateOptionsMenu() method is called
only once, as described above. The
system keeps and re-uses the Menu you
define in this method until your
activity is destroyed. If you want to
change the Options Menu any time after
it's first created, you must override
the onPrepareOptionsMenu() method.
This passes you the Menu object as it
currently exists. This is useful if
you'd like to remove, add, disable, or
enable menu items depending on the
current state of your application.
E.g.
#Override
public boolean onPrepareOptionsMenu (Menu menu) {
if (isFinalized) {
menu.getItem(1).setEnabled(false);
// You can also use something like:
// menu.findItem(R.id.example_foobar).setEnabled(false);
}
return true;
}
On Android 3.0 and higher, the options menu is considered to always be open when menu items are presented in the action bar. When an event occurs and you want to perform a menu update, you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().
On all android versions, easiest way: use this to SHOW a menu action icon as disabled AND make it FUNCTION as disabled as well:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item = menu.findItem(R.id.menu_my_item);
if (myItemShouldBeEnabled) {
item.setEnabled(true);
item.getIcon().setAlpha(255);
} else {
// disabled
item.setEnabled(false);
item.getIcon().setAlpha(130);
}
}
You could save the item as a variable when creating the option menu and then change its properties at will.
private MenuItem securedConnection;
private MenuItem insecuredConnection;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.connect_menu, menu);
securedConnection = menu.getItem(0);
insecuredConnection = menu.getItem(1);
return true;
}
public void foo(){
securedConnection.setEnabled(true);
}
How to update the current menu in order to enable or disable the items when an AsyncTask is done.
In my use case I needed to disable my menu while my AsyncTask was loading data, then after loading all the data, I needed to enable all the menu again in order to let the user use it.
This prevented the app to let users click on menu items while data was loading.
First, I declare a state variable , if the variable is 0 the menu is shown, if that variable is 1 the menu is hidden.
private mMenuState = 1; //I initialize it on 1 since I need all elements to be hidden when my activity starts loading.
Then in my onCreateOptionsMenu() I check for this variable , if it's 1 I disable all my items, if not, I just show them all
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_galeria_pictos, menu);
if(mMenuState==1){
for (int i = 0; i < menu.size(); i++) {
menu.getItem(i).setVisible(false);
}
}else{
for (int i = 0; i < menu.size(); i++) {
menu.getItem(i).setVisible(true);
}
}
return super.onCreateOptionsMenu(menu);
}
Now, when my Activity starts, onCreateOptionsMenu() will be called just once, and all my items will be gone because I set up the state for them at the start.
Then I create an AsyncTask Where I set that state variable to 0 in my onPostExecute()
This step is very important!
When you call invalidateOptionsMenu(); it will relaunch onCreateOptionsMenu();
So, after setting up my state to 0, I just redraw all the menu but this time with my variable on 0 , that said, all the menu will be shown after all the asynchronous process is done, and then my user can use the menu.
public class LoadMyGroups extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mMenuState = 1; //you can set here the state of the menu too if you dont want to initialize it at global declaration.
}
#Override
protected Void doInBackground(Void... voids) {
//Background work
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mMenuState=0; //We change the state and relaunch onCreateOptionsMenu
invalidateOptionsMenu(); //Relaunch onCreateOptionsMenu
}
}
Results
simplify #Vikas version
#Override
public boolean onPrepareOptionsMenu (Menu menu) {
menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
return true;
}
A more modern answer for an old question:
MainActivity.kt
private var myMenuIconEnabled by Delegates.observable(true) { _, old, new ->
if (new != old) invalidateOptionsMenu()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.my_button).setOnClickListener { myMenuIconEnabled = false }
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main_activity, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
menu.findItem(R.id.action_my_action).isEnabled = myMenuIconEnabled
return super.onPrepareOptionsMenu(menu)
}
menu_main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_my_action"
android:icon="#drawable/ic_my_icon_24dp"
app:iconTint="#drawable/menu_item_icon_selector"
android:title="My title"
app:showAsAction="always" />
</menu>
menu_item_icon_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?enabledMenuIconColor" android:state_enabled="true" />
<item android:color="?disabledMenuIconColor" />
attrs.xml
<resources>
<attr name="enabledMenuIconColor" format="reference|color"/>
<attr name="disabledMenuIconColor" format="reference|color"/>
</resources>
styles.xml or themes.xml
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="disabledMenuIconColor">#color/white_30_alpha</item>
<item name="enabledMenuIconColor">#android:color/white</item>
What I did was save a reference to the Menu at onCreateOptionsMenu. This is similar to nir's answer except instead of saving each individual item, I saved the entire menu.
Declare a Menu Menu toolbarMenu;.
Then in onCreateOptionsMenusave the menu to your variable
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu, menu);
toolbarMenu = menu;
return true;
}
Now you can access your menu and all of its items anytime you want.
toolbarMenu.getItem(0).setEnabled(false);
the best solution
when you are perform on navigation drawer
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.setGroupVisible(0,false);
return true;
}
If visible menu
menu.findItem(R.id.id_name).setVisible(true);
If hide menu
menu.findItem(R.id.id_name).setVisible(false);
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item_id:
//Your Code....
item.setEnabled(false);
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.home, menu);
return false;
}
Generally can change the properties of your views in runtime:
(Button) item = (Button) findViewById(R.id.idBut);
and then...
item.setVisibility(false)
but
if you want to modify de visibility of the options from the ContextMenu, on press your button, you can activate a flag, and then in onCreateContextMenu you can do something like this:
#Override
public void onCreateContextMenu(ContextMenu menu,
View v,ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle(R.string.context_title);
if (flagIsOn()) {
addMenuItem(menu, "Option available", true);
} else {
Toast.makeText(this, "Option not available", 500).show();
}
}
I hope this helps
Related
I'm inflating the menu and trying to find the view of one of the menu items in the following way:
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
// will print `null`
Log.i("TAG", String.valueOf(findViewById(R.id.action_hello)));
return true;
}
In the result null is printed in Logcat. However if I add some delay before calling findViewById, it returns correct View object:
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(final Void... voids) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(final Void aVoid) {
// will print correctly android.support.v7.view.menu.ActionMenuItemView...
Log.i("TAG", String.valueOf(findViewById(R.id.action_hello)));
}
}.execute();
return true;
}
Of course this solution is very dirty and the minimal delay is unknown. Is there a way to register some callback for the menu inflated event. In other words: how can I call findViewById with the menu item id to be sure that the view is already there and this call won't return null?
Just override public void onPrepareOptionsMenu(Menu menu).
Documentation says:
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.
The view for Menu is created after calling onCreateOptionsMenu(Menu), that's why you can't access it subviews.
There are two ways to find the menu item view.
Frist way:-
Add a actionViewClass in your menu item, so that you can get view returned by getActionView. As getActionView() only works if there's a actionView defined for menuItem.
Add this in your menu item xml:-
<item
android:id="#+id/menuAdd"
android:icon="#android:drawable/ic_menu_add"
android:title="Add"
app:showAsAction="always"
app:actionViewClass="android.widget.ImageButton" />
In onCreateOptionsMenu method:-
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_item,menu);
View menuView=menu.findItem(R.id.menuAdd).getActionView();
Log.e("TAG", "onCreate: "+menuView );
return true;
}
Second way:-
The second way is to use a handler. Using this method you won't need to specify the time for the delay. Check the answer given by #davehenry here
You must call the super method when your code is finished or things just don't work as expected.
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
super.onCreationOptionsMenu(menu);
// calling the super completes the method now you code.
Log.i("TAG", String.valueOf(findViewById(R.id.action_hello)));
return true;
}
This way you get the menu item's id and its actionview:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
MenuItem mi = menu.findItem(R.id.action_hello);
int id = mi.getItemId();
Log.i("TAG", String.valueOf(id));
View actionView = mi.getActionView();
if (actionView == null) {
Log.i("TAG", "ActionView is null");
} else {
Log.i("TAG", "ActionView is NOT null");
}
return true;
}
Posting Runnable to the Handler queue would usually have that Runnable executed after the main UI thread finished with the currently being executed method part of the Activity's lifecycle, hence it would be a good chance to get what you want there. I do need to note that it's a trick which could fail if underestimated and not well tested but it has worked for me ever since I figured it out.
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
new Handler(getMainLooper()).post(new Runnable() {
#Override
public void run() {
Logger.LogI(TAG, "run: " + findViewById(R.id.action_hello));
}
});
return true;
}
Create a global variable for future use:
private ImageButton actionHelloView;
Then, in your onCreateOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main, menu);
actionHelloView = (ImageButton) menu.findItem(R.id.action_hello).getActionView();
Log.i("the view is: ", String.valueOf(actionHelloView));
return true;
}
Put this in your XML:
<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="com.test.teststack.MainActivity">
<item
android:id="#+id/action_hello"
android:title="#string/action_settings"
app:showAsAction="never"
app:actionViewClass="android.widget.ImageButton"/>
</menu>
Note:
depending on your API version, you can switch between app:actionViewClass and android:actionViewClass in your xml.
Result in LOGCAT:
07-25 17:55:07.138 9491-9491/? I/the view is:: android.widget.ImageButton{5542a5c VFED..C.. ......I. 0,0-0,0 #7f080011 app:id/action_hello}
You don't mention why you want to find the menu item view and that may have some bearing on the answer that you are looking for. However, if you want to use findViewById() to find a menu view then this is one way to do it. The following example just changes a menu icon from an "X" to a check mark.
ViewTreeObserver.OnGlobalLayoutListener will be invoked right after layout of the toolbar in the following code. It is along the same lines as your delay, but it is the acceptable way to do this type of processing.
Alternately, the program can invoke menu.findItem(R.id.action_hello) in onPrepareOptionsMenu(). Unfortunately, the toolbar is not fully formed at this point, so a findViewById() will fail.
MainActivity.xml
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setTitle("");
toolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
ActionMenuItemView view = toolbar.findViewById(R.id.action_hello);
if (view != null) {
// onGlobalLayout may be called before toolbar is fully defined.
Log.d("onGlobalLayout", "<<<<view is not null");
// Uncomment this view to make the change to the icon here. Android Studio
// will complain about a library group, but that can be ignored for this demo.
// view.animate() might be a better demo here.
view.setIcon(getResources().getDrawable(R.drawable.ic_check));
toolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Uncomment the following line to change the icon here.
// menu.findItem(R.id.action_hello).setIcon(getResources().getDrawable(R.drawable.ic_check));
return true;
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_hello"
android:icon="#drawable/ic_x"
android:title="Item1"
app:showAsAction="ifRoom" />
</menu>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layoutDirection="ltr"
android:padding="0px"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:contentInsetEnd="0px"
app:contentInsetEndWithActions="0px"
app:contentInsetLeft="0px"
app:contentInsetRight="0px"
app:contentInsetStart="0px"
app:contentInsetStartWithNavigation="0px"
app:logo="#null"
app:title="#null"
app:titleMargin="0px"
app:titleTextColor="#757575"
tools:ignore="UnusedAttribute"
tools:title="toolbar">
</android.support.v7.widget.Toolbar>
</FrameLayout>
In onCreateOptionsMenu(), when you call
findViewById(R.id.action_hello)
this searches in the View hierarchy starting with your "content root". Since the menu you inflated hasn't been attached to the content root yet, it is likely this will return null.
You should be able to post a Runnable to a Handler that will find the View you want. This should be called after you return from onCreateOptionsMenu() and Android has attached the menu views to the content root. You shouldn't need any delay. You just need to wait until the framework has completed the creation of the options menu.
Inflating your menu is not asynchronous, so you are able to find the item exactly where you are doing so - although onPrepareOptionsMenu is probably the more correct place to do so.
What you cannot do is use findItemById, which looks in the currently showing layout (not your collapsed menu), instead you must use menu.findItem() (or menu.getItem())
If you really need to work with the view of the Item (vs the MenuItem object) you can use menu.findItem().getActionView()
In here I am having list of colleges. I favourite the particular college by using menu bar Favourite_icon.Then the Favourite_icon changed as Favourite_icon1 When the college is viewed by some other time that menu bar Favourite_icon should as Favourite_icon1. So that I am checking Whether the college is already favourited by using server API. So how can I set the menu bar Icon from oncreate() method.
If you mean the Android menu bar, you shouldn't try and change it in onCreate(), because it hasn't been instantiated, and will always throw a NullPointerException.
If you are waiting for an API response to find the favorites, you will need to create a local menu variable to access it.
Menu myMenu;
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
myMenu = menu;
return super.onPrepareOptionsMenu(menu);
}
Then, whatever your server API's callback method should do something like this:
void callback(boolean favorite) {
if (favorite) {
myMenu.findItem(R.id.myMenuItem).setIcon(R.drawable.Favourite_icon1);
}
}
Something like this:
#Override
protected void onCreate (Bundle savedInstanceState){
...
isSomethingInMenu = true;
invalidateOptionsMenu();
...
}
#Override
public boolean onCreateOptionsMenu (Menu menu){
getMenuInflater().inflate(R.menu.menu, menu);
menu.findItem(R.id.action_something).setVisible(isSomethingInMenu);
...
}
I've tried already all possible solutions. Here's my code:
private Menu mMenu;
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_article_detail_menu, menu);
mMenu = menu;
}
void changeStar(boolean added) {
if (mMenu != null) {
MenuItem item = mMenu.findItem(R.id.favourites_item);
if (added) {
Log.d(LOG_TAG, "Set full icon");
item.setIcon(getResources().getDrawable(R.drawable.star_full));
} else {
Log.d(LOG_TAG, "Set empty icon");
item.setIcon(getResources().getDrawable(R.drawable.star_empty));
}
}
}
Here is my menu xml file:
<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="ssidit.pp.ua.payspacereader.ArticleDetailActivity">
<item
android:id="#+id/refresh_item"
android:title="#string/refresh"
app:showAsAction="never"></item>
<item
android:id="#+id/favourites_item"
android:icon="#drawable/star_empty"
android:title="#string/add_to_favourite"
app:showAsAction="ifRoom"></item>
<item
android:id="#+id/share_item"
android:icon="#drawable/ic_share"
android:title="#string/share"
app:actionProviderClass="android.support.v7.widget.ShareActionProvider"
app:showAsAction="ifRoom"></item>
</menu>
invalidateMenu() method doesn't help. When I call setIcon method, nothing changes on my android device.
Here is my code:
private boolean isFavourite;
private void setValues(Cursor cursor) {
Log.d(LOG_TAG, "Setting values");
setData(titleTextView, CursorUtility.getTitle(cursor));
setData(dateTextView, CursorUtility.getDateText(cursor));
setData(timeTextView, CursorUtility.getTimeText(cursor));
isFavourite = CursorUtility.isFavourite(cursor);
getActivity().invalidateOptionsMenu();
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
Log.d(LOG_TAG, "OnPrepareOptionsMenu");
MenuItem item = menu.findItem(R.id.favourites_item);
if (isFavourite) {
Log.d(LOG_TAG, "Set full icon");
item.setIcon(R.drawable.star_full);
} else {
Log.d(LOG_TAG, "Set empty icon");
item.setIcon(R.drawable.star_empty);
}
}
As you can see, everything is logged. So there can't be mistake if some method doesn't call. Also I checked item by getting title of it. It is right item. Just some kind of black magic.
Try using invalidateOptionsMenu and move your changeStar logic to onPrepareOptionsMenu. From Android documentation:
public boolean onPrepareOptionsMenu (Menu menu)
Added in API level 1
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.
The default implementation updates the system menu items based on the activity's state. Deriving classes should always call through to the base class implementation.
Firstly: make a global variable of menu
Secondly: wherever in activity you want to change the icon just get that menu item by global variable menu using getItem() method instead of findItem.
Thirdly: set the icon to your menuItem returned by getItem() as follow menuItem.setIcon(res)
I have a Sherlock Fragment Activity in which there are 3 Fragments.
Fragment A, Fragment B, Fragment C are three fragments. I want to show a done option menu in Fragment B only.
And the activity is started with Fragment A. When Fragment B is selected done button is added.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if(!menusInflated){
inflater.inflate(R.menu.security, menu);
menusInflated=true;
}
super.onCreateOptionsMenu(menu, inflater);
}
When I again start Fragment A I want to options Menu DONE (which was set at Fragment B) for this I am doing like this
setHasOptionsMenu(false);
MenuItem item = (MenuItem) menu.findItem(R.id.done_item);
item.setVisible(false);
But this is not hiding at all, also it is giving NullPointerException when Activity if first started with Fragment A.
Please let me know what is the problem.
Try this...
You don't need to override onCreateOptionsMenu() in your Fragment class again. Menu items visibility can be changed by overriding onPrepareOptionsMenu() method available in Fragment class.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_search).setVisible(false);
super.onPrepareOptionsMenu(menu);
}
This is one way of doing this:
add a "group" to your menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<group
android:id="#+id/main_menu_group">
<item android:id="#+id/done_item"
android:title="..."
android:icon="..."
android:showAsAction="..."/>
</group>
</menu>
then, add a
Menu menu;
variable to your activity and set it in your override of onCreateOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
// inflate your menu here
}
After, add and use this function to your activity when you'd like to show/hide the menu:
public void showOverflowMenu(boolean showMenu){
if(menu == null)
return;
menu.setGroupVisible(R.id.main_menu_group, showMenu);
}
I am not saying this is the best/only way, but it works well for me.
To show action items (action buttons) in the ActionBar of fragments where they are only needed, do this:
Lets say you want the save button to only show in the fragment where you accept input for items and not in the Fragment where you view a list of items, add this to the OnCreateOptionsMenu method of the Fragment where you view the items:
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (menu != null) {
menu.findItem(R.id.action_save_item).setVisible(false);
}
}
NOTE: For this to work, you need the onCreate() method in your Fragment (where you want to hide item button, the item view fragment in our example) and add setHasOptionsMenu(true) like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Might not be the best option, but it works and it's simple.
This will work for sure I guess...
// Declare
Menu menu;
MenuItem menuDoneItem;
// Then in your onCreateOptionMenu() method write the following...
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
this.menu=menu;
inflater.inflate(R.menu.secutity, menu);
}
// In your onOptionItemSelected() method write the following...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.done_item:
this.menuDoneItem=item;
someOperation();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// Now Making invisible any menu item...
public void menuInvisible(){
setHasOptionsMenu(true);// Take part in populating the action bar menu
menuDoneItem=(MenuItem)menu.findItem(R.id.done_item);
menuRefresh.setVisible(false); // make true to make the menu item visible.
}
//Use the above method whenever you need to make your menu item visible or invisiable
You can also refer this link for more details, it is a very useful one.
MenuItem Import = menu.findItem(R.id.Import);
Import.setVisible(false)
Try this
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.custom_actionbar, menu);
menu.setGroupVisible(...);
}
By setting the Visibility of all items in Menu, the appbar menu or overflow menu will be Hide automatically
Example
private Menu menu_change_language;
...
...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
...
...
menu_change_language = menu;
menu_change_language.findItem(R.id.menu_change_language).setVisible(true);
return super.onCreateOptionsMenu(menu);
}
Before going to other fragment use bellow code:
if(menu_change_language != null){
menu_change_language.findItem(R.id.menu_change_language)
.setVisible(false);
}
Hello I got the best solution of this, suppose if u have to hide a particular item at on create Menu method and show that item in other fragment. I am taking an example of two menu item one is edit and other is delete. e.g menu xml is as given below:
sell_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_edit"
android:icon="#drawable/ic_edit_white_shadow_24dp"
app:showAsAction="always"
android:title="Edit" />
<item
android:id="#+id/action_delete"
android:icon="#drawable/ic_delete_white_shadow_24dp"
app:showAsAction="always"
android:title="Delete" />
Now Override the two method in your activity & make a field variable mMenu as:
private Menu mMenu; // field variable
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.sell_menu, menu);
this.mMenu = menu;
menu.findItem(R.id.action_delete).setVisible(false);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_delete) {
// do action
return true;
} else if (item.getItemId() == R.id.action_edit) {
// do action
return true;
}
return super.onOptionsItemSelected(item);
}
Make two following method in your Activity & call them from fragment to hide and show your menu item. These method are as:
public void showDeleteImageOption(boolean status) {
if (menu != null) {
menu.findItem(R.id.action_delete).setVisible(status);
}
}
public void showEditImageOption(boolean status) {
if (menu != null) {
menu.findItem(R.id.action_edit).setVisible(status);
}
}
That's Solve from my side,I think this explanation will help you.
You can make a menu for each fragment, and a global variable that mark which fragment is in use now.
and check the value of the variable in onCreateOptionsMenu and inflate the correct menu
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (fragment_it == 6) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.custom_actionbar, menu);
}
}
Okay I spend couple of hour to get this solution.apparently you can get menuitem from your toolbar to anywhere in activity or fragment. So in my case.
var menuItem = toolbar.menu;
Now to get specfic item from menu item
favIcon = menuItem.findItem(R.id.favourite);
Note: favIcon is MenuItem declare global
Now if you can do whatever you want to do for this icon
eg. to make it invisible
favIcon?.isVisible=false
Even though the question is old and answered. There is a simpler answer to that than the above mentioned. You don't need to use any other variables.
You can create the buttons on action bar whatever the fragment you want, instead of doing the visibility stuff(show/hide).
Add the following in the fragment whatever u need the menu item.
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
Sample menu.xml file:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_addFlat"
android:icon="#drawable/add"
android:showAsAction="ifRoom|withText"
android:title="#string/action_addFlat"/>
</menu>
Handling onclick events is as usual.
Late to the party but the answers above didn't seem to work for me.
My first tab fragment (uses getChildFragmentManager() for inner tabs) has the menu to show a search icon and uses android.support.v7.widget.SearchView to search within the inner tab fragment but navigating to other tabs (which also have inner tabs using getChildFragmentManager()) would not remove the search icon (as not required) and therefore still accessible with no function, maybe as I am using the below (ie outer main tabs with each inner tabs)
getChildFragmentManager();
However I use the below in my fragments containing/using the getChildFragmentManager() for inner tabs.
//region onCreate
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
//access setHasOptionsMenu()
setHasOptionsMenu(true);
}
//endregion onCreate
and then clear the menu item inside onPrepareOptionsMenu for fragments(search icon & functions)
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
//clear the menu/hide the icon & disable the search access/function ...
//this will clear the menu entirely, so rewrite/draw the menu items after if needed
menu.clear();
}
Works well and navigating back to the tab/inner tab with the search icon functions re displays the search icon & functions.
Hope this helps...
For some reason the method was not working for me this is how I solved it according to the accepted solution
//This should be in on create
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
showOverflowMenu(false);
}
},100);
#Override
public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
getMenuInflater().inflate(R.menu.options_menu, menu);
return true;
}
public void showOverflowMenu(boolean showMenu){
if(menu == null)
return;
menu.setGroupVisible(R.id.grp, showMenu);
}
I have a standard search EditText in my ActionBar, triggered by a touch on a little magnifying glass icon. I can cache the user's search string using the OnQueryTextListener. I want to put that string back into the EditText when the user touches the icon a second time.
I'm using ABS (soon to abandon), targeting 8-19.
How can I do this?
With a normal action bar (you'll have to find the different variation with ABS, not sure if my answer will apply completely with that library).
SearchView is a widget that can be inflated in the options menu, so what I do is inflate a menu using an XML containing an action view:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/search_user"
android:actionViewClass="android.widget.SearchView"
android:icon="#drawable/magnifing_glass"
android:showAsAction="ifRoom|collapseActionView"
android:title="Search Users"/>
</menu>
Next, when inflating the action view, set your listeners, and use a global variable to save the previous search.
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_menu, menu);
MenuItem search = menu.findItem(R.id.search_user);
//Keep a global variable of this so you can set it within the next listener
SearchView user_search = (SearchView) search.getActionView();
user_search.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
global_variable = query;
return true;
}
#Override
public boolean onQueryTextChange(String text) {
return true;
}
});
Finally, in a second listener, set the text of the global variable to your previous query when the action view expands.
//This is set on the menu item
search.setOnActionExpandListener(new OnActionExpandListener() {
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
return true; // Return true to collapse action view
}
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
user_search.setQuery(global_variable, false);
return true; // Return true to expand action view
}
});