I am developing an Android app. Firstly, let me tell you that I am not professional. What I am doing now is I am adding submenu to menu depending on a condition. But I need to do it very often in my app. But my problem is I added a submenu to the menu as first time.
But second time when I update menu depending on condition, existing submenu is not removed and new submenu is appended to navigation drawer. How can I remove submenu that is programmatically added to menu? Why my code is not removing it?
Here is my code
public void updateAuthUI()
{
isLoggedIn = tempStorage.getBoolean(getResources().getString(R.string.pref_is_logged_in),false);
Menu menu = leftDrawer.getMenu();
menu.removeItem(getResources().getInteger(R.integer.logout_item_id));
menu.removeItem(getResources().getInteger(R.integer.login_item_id));
menu.removeItem(getResources().getInteger(R.integer.register_item_id));
SubMenu authSubMenu = menu.addSubMenu("Auth");
if(isLoggedIn)
{
authSubMenu.add(1,getResources().getInteger(R.integer.logout_item_id),99,"Sign out");
}
else{
authSubMenu.add(1,getResources().getInteger(R.integer.register_item_id),97,"Register");
authSubMenu.add(1,getResources().getInteger(R.integer.login_item_id),98,"Sign in").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
openLoginActivity();
item.setChecked(true);
return true;
}
});
}
}
Here is the screenshot of my problem
As you can see Auth submenu is appended without removing existing one.
Try
authSubMenu.clear();
before your first
authSubMenu.add();
I just used SubMenu.clear() in an Android app where I was using a third-party library, and I needed to clear out an unwanted submenu from the action bar. (I actually wanted to remove the submenu completely, and this was the only way I could find to do it. It seemed to work.)
That's different from your situation, where authSubMenu is a menu you just added via menu.addSubMenu("Auth"), so you would expect it to be empty. But, as you've seen, it apparently isn't empty: rather, addSubMenu("Auth") returns the existing submenu of that title. (I can't find documentation to that effect; I'm just going by the results you've reported.)
If that really is the case, as it appears to be, then authSubMenu.clear() will remove all existing items from the submenu.
As #slymm said in a comment you can remove all menu and submenu items using
navigationView.getMenu().clear();
This can be used to remove submenu (and menu elements) and then recreate them with the new required items
Related
I'm using AppCompat and trying to recall the ImageView for the up/back button belonging to the toolbar.
I know R.android.id.home exists, because I can manage its click as a Menu item:
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
//this works
}
return super.onOptionsItemSelected(item);
}
Apart from that, whenever I try to call findViewById(android.R.id.home) - be it onCreate, be it onClick of a custom button - I get null.
I even get null if, in the sample above, I call findViewById(item.getItemId()).
Why is it?
This question has been asked before here, most times regarding ActionBarSherlock (which I am not using). Another time it was suggested to use:
getWindow().getDecorView().findViewById(android.R.id.home)
But it isn't working. In that question the OP also says findViewById(android.R.id.home) works on API>3.0, but that's not true for me. Any ideas?
Whether or not the "home" icon is a widget, and what class of widget it is, and what its ID is (if any), is up to the implementation of the action bar. The native action bar may do this differently for different API levels, and all of that may be different than the way appcompat-v7 does it. Let alone ActionBarSherlock or other action bar implementations.
Specifically, android.R.id.home is a menu ID, which is why you can use it in places like onOptionsItemSelected(). It is not necessarily a widget ID, which is why it may or may not work with findViewById().
Ideally, you do not attempt to mess with the internal implementation of a UI that you did not construct yourself.
do one really has to make his own Up button to style it?
I do not know, as I have never tried to style it.
As CommonsWare said android.R.id.home is a menu ID, not a widget ID. But if you want to access this home button you could do it. For example I needed it to highlight home button in in-app tutorial:
fun AppCompatActivity.getToolbarHomeIcon(): View? =
this.findViewById<Toolbar?>(R.id.toolbar)?.let { toolbar ->
val contentDescription: CharSequence = toolbar.navigationContentDescription.let {
if (it.isNullOrEmpty()) {
this.getString(R.string.abc_action_bar_up_description)
} else {
it
}
}
// Here home button should be created even if it doesn't exist before
toolbar.navigationContentDescription = contentDescription
ArrayList<View>().let { potentialViews ->
toolbar.findViewsWithText(
potentialViews,
contentDescription,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION
)
potentialViews.getOrNull(0)
}
}
I am currently trying to add a sub menu and get it to do what I want. I've been looking online and can't seem to see if it's possible.
Right basically I have a button called 'sign-in' which the users will press to lad the submenu in which will have a label saying Username and then an editable text box allowing the user to type in their desired user name.
Is this possible?
The code I currently have is
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
TextView txtUsername = (TextView) findViewById(R.id.txtUsername);
EditText edit_username = (EditText) findViewById(R.id.edit_username);
super.onCreateOptionsMenu(menu);
SubMenu sub = menu.addSubMenu(0,1,0, "Sign-In");
sub.add(0,11,0,edit_username); //I have noticed this is wrong but the only way I thought it would work
sub.add(0,12,0,txtUsername); //same for here
//add button for okaying the username
return true;
}
obviously this is in the create options menu but like I said I would like it to load the menu when the user clicks sign in using the signIn void
public void signIn(View view)
{
//load menu here
}
You can add any number sub menus to the menu items but you cannot nest a sub menu. (Reference)
Menus with sub menus are used in rare cases where there are a number of related sub menu items for a menu item.
You can add a submenu to an item in any menu (except a submenu) by adding a element as the child of an . Submenus are useful when your application has a lot of functions that can be organized into topics, like items in a PC application's menu bar (File, Edit, View, etc.).
Refer this document to learn more about options menu.
I don't see a point in adding the user name and password fields to an options menu. You could use a sub activity or a dialog fragment to display those fields.
In your code, you have two problems.
SubMenu sub = menu.addSubMenu(0,1,0, "Sign-In");
sub.add(0,11,0,edit_username);
sub.add(0,12,0,txtUsername);
you cannot nest submenus.
add (int groupId, int itemId, int order, CharSequence title) obviously takes CharSequence as parameter not the View widgets (your edittext and textview).
Because of some reasons, some menu item is disabled and will be enabled after the data is arrived.
Here is the case that I conern:
When the menu is current showing to user and the data is arrived, how can I enable the menu item instantly?
Now I only enable/disable menu item in onPrepareOptionsMenu(), it is only called when menu is shown again. FYI, I am using android 2.x SDK
Thank You
When the opPrepareOptionsMenu is called, it gets a reference to the Menu, so you can save this reference in a Variable, and when the data is ready add or enable de option again.
I have already done this and it is working fine. Take a look at this code...
While creating your menu add different group to each of your menu option so that you can easily handle each button seperately. like : I am giving you example of hold and resume button. One time only one button will work so how to do that here is code.
Declare this in your class.
private static final int HOLD_CALL = 0;
private static final int RESUME_CALL = 1;
Write this code in your public boolean onCreateOptionsMenu(Menu menu)
menu.add(0, HOLD_CALL, 0, "Hold Call");
menu.add(1, RESUME_CALL, 1, "Resume Call");
Use this in your public boolean onMenuOpened(int featureId, Menu menu)
menu.setGroupEnabled(1, false);`
the above code will disable your menu option. Hope it will help you If still you are facing problem then let me know i will try to help you...
i need to be able to change the options menu (the one that is shown upon pressing the menu button) on android , so that on one case (for example upon a button being pressed) , it will use a specific menu resource (XML file as in /res/menu/... ) for the menu , and on another case , use a different XML file.
so far i've seen only examples of doing it without xml (example here and here) , and they worked fine , but i want to be able to change the entire menu on some cases.
i've tried to modify the solutions i've found , but none of my trials worked.
if possible , i would prefer to re-create the menu only if the it needs to be updated with a menu resource that is different from the current one.
please help me.
If you want to change the Options Menu any time after it's first created, you must override the onPrepareOptionsMenu() method.
public boolean onPrepareOptionsMenu (Menu menu) {
menu.clear();
if (CASE_1 == 0) {
CASE_1 = 1;
getMenuInflater().inflate(R.menu.secondmenu, menu);
}
else {
CASE_1 = 0;
getMenuInflater().inflate(R.menu.firstmenu, menu);
}
return super.onPrepareOptionsMenu(menu);
}
where CASE_1 refer to the which menu you want to display depending on your requirement.
I have an options menu created and filled with several menu items. For some reason the order of the menu items when they are added is not as desired.
To guarantee the menu items are shown in the order we want it to be, a sort step is needed after the creation. But I have searched the android dev documents and found no way of doing this (or just I did not find it).
Is there any workaround to achieve this? Please advise.
Thanks!
Some sample code:
public boolean onCreateOptionsMenu(Menu menu) {
menu.add("menuItem1");
menu.add("menuItem2");
// after this I want to sort the items
ArrayList<MenuItem> list = new ArrayList<MenuItem>();
for(int i = 0; i < menu.size(); i ++) {
list.add(menu.getItem(i));
}
Collections.sort(list, new SampleComparator());
// But then I don't know how to add the sorted list of menu items back
}
You can tweak the final display order of menu items using the android:orderInCategory attribute or the order parameter of the Menu.add method. Other than those, I don't believe there's a way to sort menu items. Additionally, I'd wonder what kind of menu would require this — it may be better to use a different UI element.
You should sort items when you add like this:
menu.add (int groupId, int itemId, int order, CharSequence title)
See reference