I am making an android app and I am trying to apply some java code to the xml menu items but they are not getting inflated. I have some menu items defined within my menu xml file (stored in res/menu/main.xml) defined as follows:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".HomeActivity"
app:showAsAction="always">
<item android:id="#+id/action_close"
android:title="Close"
android:icon="#drawable/exitediting"
android:enabled="false"
app:showAsAction="always"/>
<item android:id="#+id/action_edit"
android:title="Edit"
android:icon="#drawable/editbutton"
android:enabled="false"
app:showAsAction="always"/>
<item android:id="#+id/action_mainedit"
android:title="MainEdit"
android:icon="#drawable/exitediting"
android:enabled="true"
app:showAsAction="always"/>
</menu>
Within my main activity java code I then override the menu inflator as follows:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
createAnimatorSets();
return true;
}
Then within my createAnimatorSets function I try and access the buttons like this
final ActionMenuItemView editButton = (ActionMenuItemView) toolbar.getChildAt(1).findViewById(R.id.action_edit);
final ActionMenuItemView closeButton = (ActionMenuItemView) toolbar.getChildAt(1).findViewById(R.id.action_close);
final ActionMenuItemView mainButton = (ActionMenuItemView) toolbar.getChildAt(1).findViewById(R.id.action_mainedit);
This simply returns null. I tried to put a break point at this point in the code and watch a few variables. R.id.action_edit is returning the id as expected but both findViewById(R.id.action_edit) and toolbar.getChildAt(1).findViewById(R.id.action_edit) are returning null. The toolbar itself (variable name toolbar) is there and the buttons are stored inside but they are for some reason not inflated in order to be utilised. I have also tried to do it in the onStart method rather than onCreate but this does not work either. Does anyone know how to fix this.
Thanks
You can get a reference to your MenuItems in the onCreateOptionsMenu(Menu menu) method by using
MenuItem edit = menu.findItem(R.id.action_edit);
View actionViewEdit = edit.getActionView();
once you have inflated your menu.
So after a lot of testing it seems that the menu only gets inflated in the onResume. This led to a very hacky solution to my problem but in the future if people struggle with this you need to do your stuff in onresume and just set the buttons to hidden initially within the xml if needed as I have done
Related
Kind people! Tell me how to make such an elementary thing as a disabled menu item with the appropriate appearance, as in the example from material design? Programmatically. Thank you in advance
EDIT: The following examples will disable click, but do not change the appearance according to the material design:
Code example:
#Override
public void onPrepareOptionsMenu(#NonNull Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem menuItem = menu.findItem(R.id.someItem);
menuItem.setEnable(false);
}
Xml example:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/someItem"
android:enabled="false"
android:title="Some title" />
</menu>
You can do Add, Remove, or Disable menu items and change text color of menu item at Runtime like that::
If you want to modify the options menu based on events that occur during the activity lifecycle, you can do so in the onPrepareOptionsMenu() method. This method passes you the Menu object as it currently exists so you can modify it, such as add, remove, or disable items. (Fragments also provide an onPrepareOptionsMenu() callback.)
On Android 2.3.x and lower, the system calls onPrepareOptionsMenu() each time the user opens the options menu (presses the Menu button).
On Android 3.0 and higher, the options menu is considered to always be open when menu items are presented in the app bar. When an event occurs and you want to perform a menu update, you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().
You can see the Documentation
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/someItem"
android:enabled="false"
android:title="Some title"
app:actionViewClass="android.support.v7.widget.TextView"
// if using androidX
//app:actionViewClass="androidx.appcompat.widget.AppCompatTextView"/>
</menu>
And in java code
//sample code
#Override
public boolean onPrepareOptionsMenu (Menu menu) {
//disable menu item and change text color
MenuItem menu1 = menu.findItem(R.id.yourmenuid);
menu1.setEnabled(false);
TextView textView = (TextView) menu1.getActionView();
textView.setTextColor(Color.BLACK);
return true;
}
you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().
I found a workaround on how to change the text color in the menu item. It is extremely sad that such an elementary thing is not provided out of the box. Perhaps someone has a better solution, I'll be glad to see!
MenuItem menuItem = menu.findItem(R.id.some_item);
menuItem.setEnabled(false);
SpannableString s = new SpannableString(menuItem.getTitle());
s.setSpan(new ForegroundColorSpan(Color.GRAY), 0, s.length(), 0);
menuItem.setTitle(s);
Result:
I'm creating android app which contain bottom navigation bar with 4 buttons. I would like to Preselect the 3rd button when initially app is launches rather then the First tab by which is selected by Default. I have used replace frgment to load Third Fragment initially with below code
secondFragment = new second();
replaceFragment(secondFragment);
But still, the first tab is active by default instead of the third although third fragment loads successfully
Here is the xml file from menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/bottom_action_home"
android:icon="#drawable/ic_visibility_black_24dp"
android:title="I"
app:showAsAction="always|withText" />
<item
android:id="#+id/bottom_action_notif"
android:icon="#drawable/ic_visibility_black_24dp"
android:title="II"
android:checked="true"
app:showAsAction="always|withText" />
<item
android:id="#+id/bottom_action_account"
android:icon="#drawable/ic_visibility_black_24dp"
android:title="III"
app:showAsAction="always|withText"/>
<item
android:id="#+id/bottom_action_chat"
android:icon="#drawable/ic_visibility_black_24dp"
android:title="IV"
app:showAsAction="always|withText"/>
</menu>
and activity xml file is
<android.support.design.widget.BottomNavigationView
android:id="#+id/mainBottomNav"
android:background="#color/colorblog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/bottom_menu"
android:layout_alignParentBottom="true"/>
and my java file is
mainbottomNav = findViewById(R.id.mainBottomNav);
BottomNavigationViewHelper.removeShiftMode(mainbottomNav);//disable BottomNavigationView shift mode
// FRAGMENTS
mainbottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.bottom_action_home:
return true;
case R.id.bottom_action_notif:
return true;
case R.id.bottom_action_account:
return true;
case R.id.bottom_action_chat:
default:
return false;
}
}
});
I would like to have Third Button active when application is launched i.e case R.id.bottom_action_account:
Thanks in advance.
Add this line to your code
mainbottomNav.setSelectedItemId(R.id.bottom_action_account);
If you want that part of your navigation bar to be highlighted then use as mayank said:
navBar.setSelectedItemId(R.id.menuItem);
but if you're talking about when the activity starts, either change your setContentView to the correct activity, or use setActivity to complete change to a new intent/class.
In your Java file, you can add code that looks like so:
mainBottomNav.setSelectedItemId(R.id.bottom_action_account);
You can add this to your onCreate at the end so that way it is made after the view is made so the end-user will see the third tab selected.
Cheers.
I'm trying to hide an Actionbar menu item if a shared preference is false.
I'm getting the shared preference as I want, but the menu item wont hide.
// Inflate a menu to be displayed in the toolbar
toolbar.inflateMenu(R.menu.activity_main_actionbar);
// Enable disable set start page item
if(!sharedPref.getBoolean("enable_custom_startpage", false)) {
toolbar.getMenu().findItem(R.id.setasstartpage).setVisible(false);
}
What am i doing wrong??
The right place for doing this is onPrepareOptionsMenu. From the docs,
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.
So, I would recommend you to override onPrepareOptionsMenu and then check for the Shared Prefs inside it and show menu accordingly. Something like,
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Enable disable set start page item
if(!sharedPref.getBoolean("enable_custom_startpage", false)) {
toolbar.getMenu().findItem(R.id.setasstartpage).setVisible(false);
}
return true;
}
try this
mToolbar.getMenu().findItem(id).setEnabled(false);
I hope it will work for you.
try this
invalidateOptionsMenu();
I hope it is helpful for you.
Get a MenuItem pointing to such item, call setVisible on it to adjust its visibility and then call invalidateOptionsMenu() on your activity so the ActionBar menu is adjusted accordingly.
Update: A MenuItem is not a regular view that's part of your layout. Its something special, completely different. Your code returns null for item and that's causing the crash. What you need instead is to do:
MenuItem item = menu.findItem(R.id.addAction);
Start by saving the menu globally in your activity-
Menu menuu;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
menuu=menu;
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
Have different menu.xml for you . one is having noitem and other is
containing the items you want.
menu_main.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.afixi.prasenjeetpati.notification_service.MainActivity">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
</menu>
menu_blank.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.afixi.prasenjeetpati.notification_service.MainActivity">
</menu>
Now to remove the option menu at any time do this-
menuu.clear();
getMenuInflater().inflate(R.menu.menu_blank, menuu);
and to get back the normal menu-
menuu.clear();
getMenuInflater().inflate(R.menu.menu_main, menuu);
So this is the deal, I have the following
And I want to remove it but still be able to access the menu item through the menu button, is this possible?
Here is my menu xml file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/updateShares"
android:orderInCategory="100"
android:showAsAction="never"
android:title="Refresh"/>
</menu>
And here is my code creating the menu
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_action_bar_main, menu);
return true;
}
EDIT_____________________________________________________________________
I still want the "refresh" menu to appear when you press the menu button on the phone, I just want to remove the menu bar, thats why I can't set any option menu to visible=false because then I can't see them when pressing the menu bar.
I am not sure with the mark166 answer. You can try this link also. And another thing what i have done and you can try is....
Just don't inflate the layout on click of Menu. Even dont create menu.xml file.
You can try with the following code in java file
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_MENU:
Toast.makeText(getApplicationContext(), "Do what you want to show here", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
It works for me and using same thing in app.
You just comment your code for the menu and try this one.
Hope it will help you.
You can just add in your onCreate following snippet:
this.requestWindowFeature(Window.FEATURE_NO_TITLE); so your title bar will gone.
This may help you with removing menu item https://stackoverflow.com/a/13099201/1045579
as per your second screenshot change the target SDK version to 4.0.3 so the menu ... will not visible.
I am developing an Android application which uses SlidingMenu and
ActionBarSherlock.
I want to include a MenuItem in a particular SherlockListFragment which
onClick would refresh the content. The issue I have is that the item always
overflows even though there is plenty of space. When the device is turned to
landscape orientation the item moves into the ActionBar automatically.
Can anyone help with this issue? I have set the showAsAction to "always" but
still the issue is not fixed.
This is the XML file for the menu
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu_refresh"
android:title="S"
android:showAsAction="always"
/>
</menu>
This is the code in the SherlockListFragment
#Override
public void onCreateOptionsMenu(Menu menu,
com.actionbarsherlock.view.MenuInflater inflater) {
inflater = getSherlockActivity().getSupportMenuInflater();
inflater.inflate(R.menu.fragment_news,menu);
super.onCreateOptionsMenu(menu, inflater);
}
This is what the application is currently looking like:
I need the button in the ActionBar
try to set an icon
android:icon="#drawable/ic_menu_done_holo_light"
OR use flag withText
android:showAsAction="withText|always"