android - change options menu dynamically , but by inflating from XML - android

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.

Related

How to programmaticallly remove submenu from navigation drawer in Android?

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

Why does findViewById(R.android.id.home) always return null?

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)
}
}

get drawable from Android Menu Item Icon

I have a bookmark icon in a menu item. I want to change the drawable in the icon depending on whether the bookmark has been pressed before or not.
I have two drawbles, staro (meaning star orange) or starw(meaning star white). I just want to toggle this on press.
How can I know which drawble is in the icon in public boolean onOptionsItemSelected(MenuItem item) method. Is it possible to know the drawable via the item. what I know is that item.getIcon() is not the drawble. I cannot compare item.getIcon() with R.drawable.starto
You could try
if (item.getIcon().getConstantState().equals(
getResources().getDrawable(R.drawable.starto).getConstantState()
)) {
...
}
As mentioned here
You can do the changes in onPrepareOptionsMenu() which is called every time before the menu is shown. Its suitable to show/hide options based on some dynamic data.
If you already now the condition, you can directly call
if (condition_for_orange) {
menu.findItem(resourceId).setIcon(R.drawable.staro);
} else {
menu.findItem(resourceId).setIcon(R.drawable.startw);
}
You can use Shared Preference or some other global variable which can store the state which may help you to decide which icon to show now.
you can compare these too.
you can find id of drawable by
int identifier = getResources().getIdentifier("pic1", "drawable","android.demo");
and then you can compare this with R.drawable.starto `.

master/detail template with action menu - right way to show both

Beginner here, targetting sdk v14 and v17 for my learning...no need for older support.
I am using the master/detail template and trying to get an action menu (for SEARCH) to show up both in phone and tablet view. Actually I can get it to work, but I have to duplicate up my code in both ItemDetailActivity.java and ItemListActivity.java
These are the methods that I have to have in both for SEARCH to work:
public boolean onQueryTextChange(String newText) {
public boolean onQueryTextSubmit (String query) {
public boolean onClose () {
I only want to search the "detail", not the "list".
So my question: is there a way to associate the action bar with only the list fragment? That way I can keep the search functions in 1 file.
Thanks!
I'll go ahead and answer what I (think) I know as I don't want to leave this question open.
From tracing in the debugger, it looks to me like the phone activity and the tablet activity are separate and if you want to hook up an actionmenu, you have to hook it up to both separately.

Updating option menu item which is currently showing

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...

Categories

Resources