sub menu within a menu - android

I am trying to display a menu item named "share" by clicking the menu button.
now i need to create a submenu item for this share menu item.
The sub menu item should be visible when the share menu item is clicked alternatively (when clicked first time becomes visible next time invisible and so on.).
I found few solutions which are displaying the sub menuitems but those are being displayed along with the menu item.
This is my code for creating menus
public boolean onCreateOptionsMenu(Menu m) {
m.add(1,1,0,"one").setIcon(R.drawable.icon);
m.add(1,2,0,"two").setIcon(R.drawable.icon);
m.add(1,3,0,"three").setIcon(R.drawable.icon);
m.add(1,4,0,"four").setIcon(R.drawable.icon);
m.getItem(0).setVisible(false);
m.getItem(1).setVisible(false);
return true;
}
and my onPrepareOptionsMenu()
public boolean onPrepareOptionsMenu(Menu m) {
if(isvisible)
{
isvisible = false;
m.getItem(0).setVisible(true);
m.getItem(1).setVisible(true);
}
else{
isvisible = true;
m.getItem(0).setVisible(false);
m.getItem(1).setVisible(false);
}
return super.onPrepareOptionsMenu(m);
}
I need the remaining two items to be shown when i click on the menu item rather than on the menu button.
Can anyone suggest me please

override the below method:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
return super.onPrepareOptionsMenu(menu);
}
The above method is called every time before the menu is shown.
Here you can maintain a bool and hide the submenu depending upon the condition of your check.
EDIT:
By default set bool to false and on false show the menu and set the bool to true and on next call check this bool and if it is true, set it false and make the menu invisible.use this line to make the menu visible or invisible:
menu.getItem(index).getSubMenu().getItem(index).setVisible(true);
Store the bool in sharedpreference.

Related

Why is my options menu not showing the settings menu item correctly?

I This is from https://developers.facebook.com/docs/android/scrumptious/authenticate
This is my code (identical from the tutorial) for the options menu part
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// only add the menu when the selection fragment is showing
if (fragments[SELECTION].isVisible()) {
if (menu.size() == 0) {
settings = menu.add(R.string.settings);
}
return true;
} else {
menu.clear();
settings = null;
}
return false;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
if (item.equals(settings)) {
showFragment(SETTINGS, true);
return true;
}
return false;
}
whats happening is this works most of the time but I found a test case I couldn't debug. When you logout, the menu item still shows and you have to click it to make it disappear.(it shouldn't appear at all). This wasn't a huge concern to me at the beginning but I found that when you logged in again after you clicked the menu item to make it disappear, the options menu doesn't appear at all.
I think I found the problem, I leave it up for others. From When and how often onPrepareOptionsMenu() method is called for ActionBar? ,I got that "On Android 3.0 and higher, you must call invalidateOptionsMenu() when you want to update the menu, because the menu is always open. The system will then call onPrepareOptionsMenu() so you can update the menu items."
When I logged out, even thought there were no actual menu items, the menu was still open. However when I clicked the menu when it was empty, it messed it up so that when I logged in, show wouldn't work. I don't understand that part yet. I was hoping someone can elaborate what happened during that part

Android: Change menu item from Log in to Log out

My menu has a item to Log in, but when you are logged in I want it to say Log out.
How?
If I'm going to change the item after its created, its probably through this method
#Override
public boolean onCreateOptionsMenu( Menu menu ) {
MenuInflater inflater = getMenuInflater();
inflater.inflate( R.menu.menu_main, menu );
return true;
}
Afaik the onCreateOptionsMenu() happens after the onCreate so putting any getItemId() for the menu there will give me a NullPointerException right away.
I want the app to find out if its supposed to use the string R.string.Logout if its logged in.
I dont even know what to search for for this issue. All I found was how to make a string implement names, like this answer https://stackoverflow.com/a/7646689/3064486
You should use onPrepareOptionsMenu(Menu menu) instead to update menu items
#Override
public boolean onPrepareOptionsMenu(Menu menu){
super.onPrepareOptionsMenu(menu);
MenuItem someMenuItem = menu.findItem(R.id.some_menu_item);
someMenuItem.setTitle("Log out");
return super.onPrepareOptionsMenu(menu);
}
To refresh Menu items call invalidateOptionsMenu();from Activity
From Android API guides: "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.)"
After you inflate a menu, you can customize its items. To get each one, you must call findItem() with the item's id. In particular, you can use setTitle() to change the displayed string.
For example:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
if (mIsLoggedIn)
menu.findItem(R.id.action_login).setTitle("Log out");
return true;
}
where action_login is the id you set for this particular menu item in the menu's xml file.
private void updateUI() {
runOnUiThread(new Runnable() {
#Override
public void run() {
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
Menu menu = navigationView.getMenu();
MenuItem nav_signin = menu.findItem(R.id.nav_signin);
nav_signin.setTitle(MyApp.signedIn ? "Sign out" : "Sign in");
}
});
}

Menu button works just ONE time

I want to show a Menu when click a specific image :
popup_but = (ImageView) findViewById(R.id.imageView2);
popup_but.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showmen();
}
});
And the menu :
public void showmen() {
PopupMenu popup = new PopupMenu(First.this, popup_but);
popup.getMenuInflater().inflate(R.menu.popup, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId())
{
case R.id.men1:
//do something
return true;
case R.id.men5:
finish();
return true;
}
return true;
}
});
popup.show();
}
It. works. now i want to do the same when click the hardware menu button. so i use this code :
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
showmen();
}
The problem is here : when menu button clicked it just show menu for the FIRST time
Take a look in the onPrepareOptionsMenu:
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 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().
onCreateOptionsMenu() is called every time the hardware menu button is clicked, and if it returns true each time. What I do is, style the menu items using XML and then inflate the XML inside onCreateOptionsMenu() . Every time I click the hardware menu, the menu is inflated from XML. onPrepareOptionsMenu() is only for when you want to change the menu items during the lifecycle of the app. The problem, I think is in your implementation of showmen(). I think the PopupMenu.OnMenuItemClickListener is called only the first time, not every time.

How to remove items from contextual action bar android

I want to remove COPY, SELECT ALL and FIND from android contextual action bar and add custom menu items.
This is appearing while selecting text on webview. I am trying to add Text Highlights on webview using js.
In order to accomplish what you want, you will need to create an entirely new contextual action bar. This is done through creating a custom ActionMode. Within your WebView, create a nested class that implements ActionMode.Callback. You can use this as a template:
public class CustomWebView extends WebView {
private ActionMode.Callback mActionModeCallback;
#Override
public ActionMode startActionMode(ActionMode mode) {
// This block is directly from the WebView source code.
ViewParent parent = getParent();
if (parent == null) {
return null;
}
mActionModeCallback = new CustomActionModeCallback();
return parent.startActionModeForChild(this, mActionModeCallback);
}
private class CustomActionModeCallback implements ActionMode.Callback {
// Called when the action mode is created; startActionMode() was called
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
return true;
}
// Called each time the action mode is shown.
// Always called after onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// This method is called when the selection handlebars are moved.
return false; // Return false if nothing is done
}
// Called when the user selects a contextual menu item
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_button_1:
// Do stuff
break;
case R.id.menu_button_2:
// Do stuff
break;
default:
// You did not handle the action, so return false
// If you have implemented a case for every button,
// this block should never be called.
return false;
}
// If you want to close the CAB immediately after
// picking an action, call mode.finish().
// If you want the CAB to persist until the user clears the selection
// or clicks the "Done" button, simply return true.
mode.finish(); // Action picked, so close the CAB
return true;
}
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
mode = null;
}
}
}
Be sure to define a menu in your XML resources. Here is an example to go with the above template:
<!-- context_menu.xml -->
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_button_1"
android:icon="#android:drawable/menu_button_1"
android:showAsAction="always"
android:title="#string/menu_button_1">
</item>
<item
android:id="#+id/menu_button_2"
android:icon="#drawable/menu_button_2"
android:showAsAction="ifRoom"
android:title="#string/menu_button_2">
</item>
</menu>
I noticed you did not explicitly state that you want to replace SHARE and WEB SEARCH. Unfortunately, this method does require you to implement all functionality on your own. However, you can dig into the source code (I would start in ActionMode.java) for those functions. Implement a new case in CustomActionModeCallback.onActionItemClicked (where you handle your button events), copy/paste the functionality from source, and add a corresponding button in your XML file. You can even use the native icon for those functions: android:icon="#android:drawable/[name_of_desired_icon]
For reference, this information is from the Android Developers website.
http://developer.android.com/guide/topics/ui/menus.html#CAB
May be this helps you and also stack members...
https://github.com/btate/BTAndroidWebViewSelection

How to invoke the ActionBar's ContextMenu-like behavior?

In Android 3.0, when you select some text for example, the ActionBar switches to a ContextMenu-like mode, which enables you to do actions with the selected text: copy/share/etc, and a "Done" button appears on the left side to enable the user to leave this mode.
How can I switch the ActionBar into this mode in my app (with my menu items of course)? I just couldn't find this in the docs.
To use the new contextual action bar, see "Enabling the contextual action mode for individual views".
It states:
If you want to invoke the contextual action mode only when the user selects specific
views, you should:
Implement the ActionMode.Callback interface. In its callback methods, you
can specify the actions for the contextual action bar, respond to click events on action items, and handle other lifecycle events for the action mode.
Call startActionMode() when you want to show the
bar (such as when the user long-clicks the view).
For example:
Implement the ActionMode.Callback interface:
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
// Called when the action mode is created; startActionMode() was called
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
return true;
}
// Called each time the action mode is shown. Always called after onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false; // Return false if nothing is done
}
// Called when the user selects a contextual menu item
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_share:
shareCurrentItem();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
};
Notice that these event callbacks are almost exactly the same as the callbacks for the options menu, except each of these also pass the ActionMode object associated with the event. You can use ActionMode APIs to make various changes to the CAB, such as revise the title and
subtitle with setTitle() and setSubtitle() (useful to indicate how many items are
selected).
Also notice that the above sample sets the mActionMode variable null when the
action mode is destroyed. In the next step, you'll see how it's initialized and how saving
the member variable in your activity or fragment can be useful.
Call startActionMode() to enable the contextual
action mode when appropriate, such as in response to a long-click on a View:
someView.setOnLongClickListener(new View.OnLongClickListener() {
// Called when the user long-clicks on someView
public boolean onLongClick(View view) {
if (mActionMode != null) {
return false;
}
// Start the CAB using the ActionMode.Callback defined above
mActionMode = getActivity().startActionMode(mActionModeCallback);
view.setSelected(true);
return true;
}
});
When you call startActionMode(), the system returns
the ActionMode created. By saving this in a member variable, you can
make changes to the contextual action bar in response to other events. In the above sample, the
ActionMode is used to ensure that the ActionMode instance
is not recreated if it's already active, by checking whether the member is null before starting the
action mode.
Enabling batch contextual actions in a ListView or GridView
If you have a collection of items in a ListView or GridView (or another extension of AbsListView) and want to
allow users to perform batch actions, you should:
Implement the AbsListView.MultiChoiceModeListener interface and set it
for the view group with setMultiChoiceModeListener(). In the listener's callback methods, you can specify the actions
for the contextual action bar, respond to click events on action items, and handle other callbacks
inherited from the ActionMode.Callback interface.
Call setChoiceMode() with the CHOICE_MODE_MULTIPLE_MODAL argument.
For example:
ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// Here you can do something when items are selected/de-selected,
// such as update the title in the CAB
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Respond to clicks on the actions in the CAB
switch (item.getItemId()) {
case R.id.menu_delete:
deleteSelectedItems();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate the menu for the CAB
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context, menu);
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
// Here you can make any necessary updates to the activity when
// the CAB is removed. By default, selected items are deselected/unchecked.
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// Here you can perform updates to the CAB due to
// an invalidate() request
return false;
}
});
That's it. Now when the user selects an item with a long-click, the system calls the onCreateActionMode()
method and displays the contextual action bar with the specified actions. While the contextual
action bar is visible, users can select additional items.
In some cases in which the contextual actions provide common action items, you might
want to add a checkbox or a similar UI element that allows users to select items, because they
might not discover the long-click behavior. When a user selects the checkbox, you
can invoke the contextual action mode by setting the respective list item to the checked
state with setItemChecked().
Yeah, I couldn't find it either -- I had to ask at Google I|O.
Use startActionMode(). Here is one of their samples that demonstrates it. I need to do more work in this area myself.
Maybe a bit late but here's a tutorial for the actionmode:
http://www.vogella.com/articles/AndroidListView/article.html#listview_actionbar

Categories

Resources