Change MenuItem text in onMenuItemSelected - android

I'm trying to change dynamically the text of one of my button in my FabSpeedDial. When the user tap on a specific menu of this FAB, I want to change the text of this menu item but it doesn't work, nothing change...
#Override
public boolean onMenuItemSelected(MenuItem menuItem) {
if (menuItem.getItemId() == R.id.action_one) {
menuItem.setTitle(getString(R.string.my_new_text)); // doesn't work
} else if (menuItem.getItemId() == R.id.action_two) {
} else if (menuItem.getItemId() == R.id.action_three) {
}
return false;
}
Any ideas ?

Call
invalidateOptionsMenu();
after menuItem.setTitle("Any title"); to populate changes

your should invalidate the menu so that it will have an impact on UI.
menuItem.setTitle(getString(R.string.my_new_text));
invalidateOptionsMenu();

Related

How to handle ActionBar's icons visibility when using SearchView

Well, what I want is to:
Initialize ActionBar with all items, except "searchSettings";
When click on the Search icon, searchSettings appears and the rest of the icons disappear;
When close the search EditText (pressing device's back button or ActionBar's back button), ActionBar returns to its original state (all icons appearing, except "searchSettings").
My actual code is the following:
(I've imported android.support.v7.widget.SearchView instead of android.widget.SearchView. When I was using android.widget.SearchView this worked fine but other things don't)
private MenuItem searchIteam, searchSettings;
private SearchView searchView;
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menuMain);
searchItem = menu.findItem(R.id.search);
searchSettings = menu.findItem(R.id.action_searchSettings);
searchView = (SearchView)MenuItemCompat.getActionView(item);
searchSettings.setVisible(false); // hide searchSettings Item when Menu is created
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
(...)
return false;
}
});
// Detect SearchView icon clicks
searchView.setOnSearchClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setItemsVisibility(menuMain, item, false);
searchSettings.setVisible(true);
}
});
// Detect SearchView close
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
#Override
public boolean onClose() {
supportInvalidateOptionsMenu(); //shouldn't this reload the Action Bar as it was when onCreate?
return true;
}
});
return super.onCreateOptionsMenu(menu);
}
private void setItemsVisibility(Menu menu, MenuItem exception, boolean visible) {
for (int i=0; i<menu.size(); ++i) {
MenuItem item = menu.getItem(i);
if (item != exception) item.setVisible(visible);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
supportInvalidadeOptionsMenu();
super.onBackPressed();
}
This code doesn't work, when I press "back" first time, it only closes the Search's EditText and the icons don't change. If I press back again, the Activity goes a level up but I can see the icons getting as the beginning (getting as they should when I pressed "back" for the first time) a little while before the Activity close...
--- EDIT ---
Currently, if I click on Search ActionBar Icon, and then begin to press "Back Button" repeatedly, the following happens:
1st pressing: the keyboard hides, but the search EditText is still open;
2nd pressing: the searching ends (search EditText closes and the normal activity's content is shown);
3rd pressing: the activity closes.
Then, for testing purposes, I did this:
boolean pressed1, pressed2, pressed3;
searchView.setOnSearchClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pressed1 = false;
pressed2 = false;
pressed3 = false;
setItemsVisibility(menuMain, item, false);
searchSettings.setVisible(true);
}
});
#Override
public void onBackPressed() {
if (!pressed1) {
pressed1 = true;
}
else if(!pressed2) {
pressed2 = true;
}
else if(!pressed3) {
pressed3 = true;
supportInvalidateOptionsMenu();
}
else {
super.onBackPressed();
}
}
And now, what happens is:
1st pressing: the keyboard hides, but the search EditText is still open;
2nd pressing: the searching ends (search EditText closes and the normal activity's content is shown);
3rd pressing: nothing happens;
4th pressing: nothing happens;
5th pressing: the ActionBar reloads as I wanted;
6th pressing: the activity closes;
--- EDIT 2 ---
Then I've changed to this:
#Override
public void onBackPressed() {
if (!pressed1) {
pressed1 = true;
onBackPressed();
}
else if(!pressed2){
pressed2 = true;
onBackPressed();
}
else if(!pressed3){
pressed3 = true;
supportInvalidateOptionsMenu();
}
else {
super.onBackPressed();
}
}
What is happening now is:
1st pressing: the keyboard hides, but the search EditText is still open;
2nd pressing: the searching ends (search EditText closes and the normal activity's content is shown);
3rd pressing: the ActionBar reloads as I wanted;
4th pressing: the activity closes;
--- EDIT 3 --- (SOLUTION) ---
I guess that the methods setOnSearchClickListener and setOnCloseListener are from android.widget.SearchView... As I've imported android.support.v7.widget.SearchView instead, I've changed them to:
MenuItemCompat.setOnActionExpandListener(searchItem,
new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem menuItem) {
setItemsVisibility(menu, searchItem, false);
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem menuItem) {
supportInvalidateOptionsMenu();
return true;
}
});
Now it's working just fine (:
I hope I get you right: the first time you press BACK, the keyboard gets hidden. The second time you press BACK, the app quits.
If this is the case, then everything works fine. Becuase this is what super.onBackPressed() is supposed to do. It will try to hide the keyboard if it's shown. If not, it will try to go the previous activity. If there is none, it will quit the app.
So what you need to do is play with the onBackPressed() method. Basically, you don't necessarily need to call the super method if you are sure what you should do.
#Override
public void onBackPressed() {
if ( isSearching) {
supportInvalidadeOptionsMenu();
isSearching = false;
} else {
super.onBackPressed();
}
}
So now, when never you press BACK button, the activity will check if isSearching, and decide to re-render the action bar or take its normal actions as usual.
You'll need to add some logic to set the boolean flag isSearching, for example, set isSearching to true when clicking the Search.
I 'm not sure if supportInvalidadeOptionsMenu() would reset your action bar. Anyway, you can adjust the visibility for each view instead.

Creating Separate OnClick Listeners for Left and Right Navigation Drawers

I currently have two navigation drawers/menus:
However I need a little bit of help setting up an OnClick listener for the right Action Bar menu.
Currently - I have an onclick listener for the left Action Bar Menu
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
However I'm not sure how I might be able to handle an onClick event for the right Action Bar menu.
Any suggestions are greatly appreciated.
Full XML and Java Source:
http://pastebin.com/ygyyjtLZ
Try this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
} else {
switch (item.getItemId()) {
case R.id.action_more: // change the action_more with your own id in main.xml menu
// do your stuff here (your right click method)
return true;
// rest of your menu actions here...
}
}
return super.onOptionsItemSelected(item);
}

How can I add an Action after clicking on an ActionBar's Button?

I want to add a new button to the ActionBar. When I click it, it does a specific Action. So I don't want a button that, after being pressed, opens a sub-menu (like the classic 3-dot menu).
I created a new button, this:
<item android:id="#+id/action_refresh"
android:icon="#drawable/refresh"
android:title="#string/refresh_string"
android:showAsAction="always"/>
and it's shown on the ActionBar, but if I click it, naturally, it doesn't do anything.
How can I manage to get an Action just pressing it?
Thanks!
You Need to override onOptionsItemSelected
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_refresh:
//do your stuff
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Same as Homo sapiens's answer, but with an if-structure.
Add this method to your Activity class:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == R.id.action_refresh)
{
// do your stuff
return true;
}
else if (item.getItemId() == R.id.otherItem)
{
// do other stuff
return true;
}
// ...
else
{
return super.onOptionsItemSelected(item);
}
}

openOptionsMenu function not working in ICS?

Im using action bar compability library. Im trying to open the options menu from a button with openOptionsMenu() function but it does nothing.
Menu shows as usual when pressing the menu key on my phone. What is wrong here?
public class ReadActivity extends ActionBarActivity {
...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean value;
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.read, menu);
value = super.onCreateOptionsMenu(menu);
if (Helper.SupportsNewApi()) {
getActionBar().hide();
} else {
((View) ((LinearLayout) findViewById(R.id.actionbar_compat))
.getParent()).setVisibility(View.GONE);
}
return value;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
case R.id.menu_search:
// Toast.makeText(this, "Tapped search", Toast.LENGTH_SHORT).show();
break;
case R.id.menu_bookmark:
// selectText();
// setFullScreen(false);
break;
case R.id.menu_day_night_mode:
break;
case R.id.menu_settings:
break;
case R.id.menu_zoom_in:
showOverlay(false);
break;
case R.id.menu_zoom_out:
showOverlay(false);
break;
case R.id.menu_table_of_contents:
Intent tocIntent = new Intent(this, TocActivity.class);
int GET_SECTION_REFERENCE = 1;
startActivityForResult(tocIntent, GET_SECTION_REFERENCE);
break;
case R.id.menu_overflow:
Toast.makeText(this, "Tapped overflow", Toast.LENGTH_SHORT).show();
//closeOptionsMenu();
openOptionsMenu(); //tried the below aswell, no results
//getWindow().openPanel(Window.FEATURE_OPTIONS_PANEL, null);
break;
}
return super.onOptionsItemSelected(item);
}
#Override //disable volume buttons
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (!menuShown && (keyCode == 25 || keyCode == 24)) {
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
Log.d(tag, "Keycode is = "+keyCode);
if (keyCode == 82) {
if (!menuShown) {
//openOptionsMenu();
showOverlay(true);
} else {
showOverlay(false);
}
//don't want it to open when pressing menu
return true;
} else if (keyCode == 4 && menuShown) {
showOverlay(false);
return true;
} else if (keyCode == 25 && !menuShown) {
prevPage();
return true;
} else if (keyCode == 24 && !menuShown) {
nextPage();
return true;
}
return super.onKeyUp(keyCode, event);
}
}
I was having the same problem trying to go around this openOptionsMenu thing on an app
that I was doing that should run on Android 1.6 and up. Following the answer from Werner Van Belle I reached the conclusion that we could achieve a workaround to solve the problem.
So I came up with the following code, it's always beatiful when people don't mark a method as final, so we can always override it. It's perfect if you don't want to give up on targeting your app to the latest api (android:targetSdkVersion="17"). I hope you guys like it. :)
#Override
public void openOptionsMenu() {
Configuration config = getResources().getConfiguration();
if((config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK)
> Configuration.SCREENLAYOUT_SIZE_LARGE) {
int originalScreenLayout = config.screenLayout;
config.screenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
super.openOptionsMenu();
config.screenLayout = originalScreenLayout;
} else {
super.openOptionsMenu();
}
}
To shed some light on this sad development by google. Google obviously wishes everybody to embrace the new ActionBar. They could have achieved that by making the ActionBar easier to use than the old menu system. That is however not how they planned the transition. No, they thought it would make sense to harras programmers by making the old menus impossible to use but without providing proper backward compatibility.
Below is the code taken from com.android.internal.policy.impl, which is supposed to create the optionsMenu panel. As you see, the code simply refuses to create an options Panel. Allthough, the ability is obviously there. So, to answer your question: forget it, Google doesn't want you to use that optionsPanel anymore.
// Don't open an options panel for honeycomb apps on xlarge devices.
// (The app should be using an action bar for menu items.)
if (st.featureId == FEATURE_OPTIONS_PANEL) {
Context context = getContext();
Configuration config = context.getResources().getConfiguration();
boolean isXLarge = (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) ==
Configuration.SCREENLAYOUT_SIZE_XLARGE;
boolean isHoneycombApp = context.getApplicationInfo().targetSdkVersion >=
android.os.Build.VERSION_CODES.HONEYCOMB;
if (isXLarge && isHoneycombApp) {
return;
}
}
I cannot understand the forcing blocking Menu button usage as well. However, the following trick helped me with showing a menu on "restricted" types of devices.
First of all we need to define, whether we require the following hack or not.
boolean requireDirtyMenuButtonHack = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && (activity.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_XLARGE) > 0;
Then:
protected final OnClickListener mMenuButtonClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
if (requireDirtyMenuButtonHack) {
Configuration config = getContext().getResources().getConfiguration();
config.screenLayout &= ~Configuration.SCREENLAYOUT_SIZE_XLARGE;
config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
getActivity().openOptionsMenu();
}
};
Don't forget to cleanup! (don't know if it's neccessary, but better to play kind)
public void onPrepareOptionsMenu(Menu menu) {
if (requireDirtyMenuButtonHack) {
Configuration config = getContext().getResources().getConfiguration();
config.screenLayout &= ~Configuration.SCREENLAYOUT_SIZE_LARGE;
config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE;
}
//do the preparing...
}
I'm not sure how relevant this is, but this forum post I found seems to be answerring the same question you have.
I hope this post is relevant enough to solve your problem.
Good luck!
android:targetSdkVersion="10" in manifest helped me.
openOptionsMenu() works as expected now on ICS+. In addition, there is "overflow" menu button appears at the bottom of screen (on device buttons panel).
ps: I use NoTitleBar theme (NoActionBar for sdk 11 and higher) +ViewPagerIndicator by Jake Wharton.
This worked for me, my code is pretty similar to yours, and what I want to do is from a button in the action bar, open the overflow menu:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_home_about:
dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.customdialog);
dialog.show();
break;
default:
case R.id.menu_home_refresh:
updateLists(true);
break;
case R.id.menu_home_menu:
new Handler().postDelayed(new Runnable() {
public void run() {
openOptionsMenu();
}
}, 0);
return true;
}
return false;
}
Do you mean you want to show a button on the right side of the action bar?
Here is how I did mine:
res/menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu_share"
android:title="Logout"
android:icon="#android:drawable/ic_lock_power_off"
android:orderInCategory="1"
android:showAsAction="always" />
</menu>
Activity
1) take note of the ActionBarActivity; 2) MenuInflater in onCreateOptionsMenu 3) onOptionsItemsSelected (I think you need to return super.onOptionsItemSelected(item) )
public class BaseActivity extends ActionBarActivity {
....
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
....
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_share:
//Do something
break;
}
return super.onOptionsItemSelected(item);
}
If you are using your custom toolbar, you can try:
toolBar.showOverflowMenu();

How do I keep a menu item group open when rotating android device

I've handled screen rotation config changes in the android manifest, which works for dialog themed activities, however for these menu groups, which open after selecting a menu item (in onOptionsItemSelected) still close when I rotate the screen. Can I handle these in onConfigurationChanged? Or is there a better way? I've attached the code that opens the submenu.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getGroupId() == R.id.submenu) {
if (item.getItemId() == this.submenu) {
return true;
}
this.value = item.getItemId();
item.setChecked(true);
//do something with value
return true;
}
//...
return super.onOptionsItemSelected(item);
}
you will need to override
#Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
}
But to do this you must specify the configuration change you will handle yourself by adding to the manifest file on the Activity level the tag
android:configChanges=["mcc", "mnc", "locale",
"touchscreen", "keyboard", "keyboardHidden",
"navigation", "orientation", "screenLayout",
"fontScale", "uiMode"]
on onConfigurationChanged save the state and reload it on onResume
This ended up being a very simple fix. I needed to add the line android:configChanges="orientation" to my activity in the AndroidManifest.

Categories

Resources