How do i set my menu buttons location - android

So what i want to do, is to have that menu button that we all know, to be displayed in the top right corner.
And as I've searched online, I found that actionbar Sherlock kind of suites my needs.
As you can see from he pic, the code that I use, adds that darker blue part in my design (the one that I ilustrated in a red rectangle using my awesome paint skills), and i want that button that is a green circle, to be placed in the area where the green arrow (nice movie :D) points.
The only code that i used to display this is below, and it is taken from the Sherlock demos:
ActionMode mMode;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMode = startActionMode(new AnActionModeOfEpicProportions());
}
private final class AnActionModeOfEpicProportions implements ActionMode.Callback {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//Used to put dark icons on light action bar
// boolean isLight = SampleList.THEME == R.style.Theme_Sherlock_Light;
menu.add("Feedback")
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
menu.add("Share")
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
menu.add("Preferences")
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
menu.add("Refresh")
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Toast.makeText(AndroidMenu.this, "Got click: " + item, Toast.LENGTH_SHORT).show();
mode.finish();
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
}
I can't seem to figure out where that design comes from (probably the Sherlock framework), and how can i modify it like I want...
Any ideas guys ?
EDIT:
The answer that I found is to use a different Sherlock Sample for my goal :
public class SubMenus extends SherlockActivity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
SubMenu subMenu1 = menu.addSubMenu("Action Item");
subMenu1.add("Sample");
subMenu1.add("Menu");
subMenu1.add("Items");
MenuItem subMenu1Item = subMenu1.getItem();
subMenu1Item.setIcon(R.drawable.ic_title_share_default);
subMenu1Item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
SubMenu subMenu2 = menu.addSubMenu("Overflow Item");
subMenu2.add("These");
subMenu2.add("Are");
subMenu2.add("Sample");
subMenu2.add("Items");
MenuItem subMenu2Item = subMenu2.getItem();
subMenu2Item.setIcon(R.drawable.ic_compose);
return super.onCreateOptionsMenu(menu);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(SampleList.THEME); //Used for theme switching in samples
super.onCreate(savedInstanceState);
setContentView(R.layout.text);
((TextView)findViewById(R.id.text)).setText(R.string.submenus_content);
}

The best way to personalize such objects is to set a custom View on them. Perhaps you can inflate a custom layout which provides one TextView and a Button on the right, without the "Done" mark on the left.
This is a snippet of code from this
LayoutInflater inflater = LayoutInflater.from(getSherlockActivity());
View actionView = inflater.inflate(R.layout.actionmode, null);
ActionMode am = getSherlockActivity().startActionMode(mActionModeCallback);
am.setCustomView(actionView);

Related

Remove CAB but preserve webview text selection

I want to implement my own custom view (not inflating a menu item), I'm planning to use a toolbar to appear each time contextMenu starts, and hide it when finished.
the problem is: there are only answer showing HOW to clear/inflate another menu over the default actionMode menu
what i`ve tried so far:
-> Use a custom contextual action bar for WebView text selection
Overriding the callback at the WebView
#Override
public ActionMode startActionMode(ActionMode.Callback callback) {
callback2 = new customCallBack();
return super.startActionMode(callback2);
}
public class customCallBack implements ActionMode.Callback {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
}
changing the return false to true, doesn't result in the desired behavior i.e. hide the cab
Overriding the OnLongClick is not a option too, since it disable the current selection.
This answer solves the problem:
android webview: prevent text selection actionMode actionBar
not the most elegant solution ever, but I just tested it in an app I'm building and it works like a charm.
The Only way that worked for me (only on on Android L+) is clearing all the menu items from context actionbar from the activity
#Override
public void onActionModeStarted(ActionMode mode) {
if (mActionMode == null) {
mActionMode = mode;
Menu menu = mode.getMenu();
// Remove the default menu items (select all, copy, paste, search)
menu.clear();
}
Toast.makeText(this, "onActionModeStarted", Toast.LENGTH_SHORT).show();
super.onActionModeStarted(mode);
}
#Override
public void onActionModeFinished(ActionMode mode) {
mActionMode = null;
Toast.makeText(this, "onActionModeFinished", Toast.LENGTH_SHORT).show();
super.onActionModeFinished(mode);
}
inspired by Use a custom contextual action bar for WebView text selection
Also I wasn't able to implement the custom menu usin popupWindow or dialogs or dialog fragments.
So simply put it with the webView in a frame layout and play with its visability and margin

Formatting Menu for Edittext in Android

I trying to create a note apps that have an ability to format the selected text in EditText like the one I usually use in Onenote. But everytime I click my menu icon, the selected text in EditText is resetted and the menu is closed itself.
This is my code in my custom Edit Text
public void init()
{
this.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.edit_text_menu, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
});
}
Menu Layout
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/action_bold"
android:title="Bold"/>
<item android:id="#+id/action_underline"
android:title="Underline"/>
<item android:id="#+id/action_italic"
android:title="Italic"/>
</menu>
the screenshot of onenote menu
http://i57.tinypic.com/zlriu9.png
and screenshot of my apps
http://i58.tinypic.com/2yjwlys.jpg
What is the right way to make a menu for EditText to format just the selected text?
Update! Already found a solution that I think work this far
I just need to override the onWindowFocusChanged function, so when I click another menu, it won't lose its selection.

How to add more options to Android default Contextual Action Bar

As we know, by default, after selecting some text on views, android displays Contextual Action Bar (CAB) with some default options, such as: copy, cut, select all...
Now, I want to have an application (that has only 2 options: ON/OFF), If I turn it ON, Some other options will be added to default CAB. If I turn it OFF, my custom options will be removed from Android default CAB.
My question is: Is it possible to Add/Remove some options to this default CAB? How can I make above application?
Thank you!
You'll have to use the setCustomSelectionActionModeCallback on each of your TextViews.
You can have a boolean:
boolean on = true;
Then create a method that actually edits the CAB like so:
private void editContextualActionBar(ActionMode actionMode, Menu menu) {
if (on) {
// adds a new menu item to the CAB
// add(int groupId, int itemId, int order, int titleRes)
menu.add(0, R.id.action_to_be_performed, 1, R.string.action_name);
} else {
// removes the new menu item
menu.removeItem(R.id.action_to_be_performed);
}
}
Finally, call the Callback on your TextView with the editContextualActionBar method in onCreateActionMode and perform the menu action in onActionItemClicked:
textView.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
editContextualActionBar(mode, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_to_be_performed:
// perform action
return true;
default:
break;
}
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
});

Use a custom contextual action bar for WebView text selection

I have used this guide from Google and this tutorial to produce my own contextual action bar.
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.annotation_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.custom_button:
// do some stuff
break;
case R.id.custom_button2:
// do some other stuff
break;
default:
// This essentially acts as a catch statement
// If none of the other cases are true, return false
// because the action was not handled
return false;
}
finish(); // An action was handled, so close the CAB
return true;
}
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
};
This menu is designed to appear when the user selects text, so it overrides the native copy/paste menu. Now I get to my issue.
Because I am overriding functions for text selection, I also added a LongClickListener to a WebView and implemented the onLongClick(View v) method so I can detect when users make the selection.
myWebView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (mActionMode != null) {
return false;
}
mActionMode = startActionMode(mActionModeCallback);
v.setSelected(true);
return true;
}
});
When I long click, I see my custom menu appear, but no text is highlighted.I need to have the text selection functionality; without it, my menu is pointless.
How do I override onLongClick(View v), but maintain the text selection provided by Android?If that is not possible, can I make the call to startActionMode(mActionModeCallback) somewhere else so that text will be selected as normal, but my custom menu will also appear?If neither of those are possible... help.
THERE IS AN EASIER WAY! See update below :D
For the sake of completeness, here is how I fixed the problem:
I followed the suggestion according to this answer, with a little more tweaking to more closely match the overridden code:
public class MyWebView extends WebView {
private ActionMode mActionMode;
private mActionMode.Callback mActionModeCallback;
#Override
public ActionMode startActionMode(Callback callback) {
ViewParent parent = getParent();
if (parent == null) {
return null;
}
mActionModeCallback = new CustomActionModeCallback();
return parent.startActionModeForChild(this, mActionModeCallback);
}
}
Essentially, this forces your customized CAB to appear instead of the Android CAB. Now you have to modify your callback so that the text highlight will go away along with the CAB:
public class MyWebView extends WebView {
...
private class CustomActionModeCallback implements ActionMode.Callback {
...
// Everything up to this point is the same as in the question
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
clearFocus(); // This is the new code to remove the text highlight
mActionMode = null;
}
}
}
That's all there is to it. Be aware that as long as you are using MyWebView with the overridden startActionMode there is NO WAY to get the native CAB (the copy/paste menu, in the case of a WebView). It may be possible to implement that sort of behavior, but that is not the way this code works.
UPDATE: There is a much easier way to do this! The above solution works well, but here is an alternative, easier way.
This solution provides less control over the ActionMode, but it requires far less code than the above solution.
public class MyActivity extends Activity {
private ActionMode mActionMode = null;
#Override
public void onActionModeStarted(ActionMode mode) {
if (mActionMode == null) {
mActionMode = mode;
Menu menu = mode.getMenu();
// Remove the default menu items (select all, copy, paste, search)
menu.clear();
// If you want to keep any of the defaults,
// remove the items you don't want individually:
// menu.removeItem(android.R.id.[id_of_item_to_remove])
// Inflate your own menu items
mode.getMenuInflater().inflate(R.menu.my_custom_menu, menu);
}
super.onActionModeStarted(mode);
}
// This method is what you should set as your item's onClick
// <item android:onClick="onContextualMenuItemClicked" />
public void onContextualMenuItemClicked(MenuItem item) {
switch (item.getItemId()) {
case R.id.example_item_1:
// do some stuff
break;
case R.id.example_item_2:
// do some different stuff
break;
default:
// ...
break;
}
// This will likely always be true, but check it anyway, just in case
if (mActionMode != null) {
mActionMode.finish();
}
}
#Override
public void onActionModeFinished(ActionMode mode) {
mActionMode = null;
super.onActionModeFinished(mode);
}
}
Here is an example Menu to get you started:
<!-- my_custom_menu.xml -->
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/example_item_1"
android:icon="#drawable/ic_menu_example_1"
android:showAsAction="always"
android:onClick="onContextualMenuItemClicked"
android:title="#string/example_1">
</item>
<item
android:id="#+id/example_item_2"
android:icon="#drawable/ic_menu_example_2"
android:showAsAction="ifRoom"
android:onClick="onContextualMenuItemClicked"
android:title="#string/example_2">
</item>
</menu>
That's it! You're done! Now your custom menu will show up, you don't have to worry about the selection, and you barely have to concern yourself with the ActionMode lifecycle.
This works nearly flawlessly with a WebView that occupies its entire parent Activity. I am not sure how well it will work if there are multiple Views within your Activity at one time. It will likely require some tweaking in that case.
The way I did something similar was to only override the onTouchListener and to invoke a GestureDetector to detect when the WebView was long-pressed and do what I wanted from there. Here's some sample code that allows you to catch long-press events without sacrificing text-selection in the WebView. Hopefully this helps.
#Override
protected void onCreate(Bundle savedInstanceState) {
WebView mWebView = (WebView) findViewById(R.id.myWebView);
GestureDetector mGestureDetector = new GestureDetector(this, new CustomGestureListener());
mWebView.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View view, MotionEvent arg1) {
//Suggestion #1 - this just lets the touch to be handled by the system but allows you to detect long presses
mGestureDetector.onTouchEvent(arg1);
return false;
//Suggestion #2 - this code will only let the touch be handled by the system if you don't detect a long press
return mGestureDetector.onTouchEvent(arg1);
}
});
}
private class CustomGestureListener extends SimpleOnGestureListener {
#Override
public void onLongPress(MotionEvent e) {
//do stuff
}
}

Item title not displayed in portrait with SHOW_AS_ACTION_WITH_TEXT

In my activity, I have an action mode with a single item which has a title and an icon.
I want both the title and the icon to be displayed, so I use SHOW_AS_ACTION_WITH_TEXT and SHOW_AS_ACTION_ALWAYS flags.
In landscape orientation, it's fine. I have title + icon.
But in portrait orientation only the icon is displayed (though there's a lot of free space). Does anyone know what I could do to fix it ?
Note that the title is correctly displayed if I remove the icon.
Here is my sample code:
public class TestActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startActionMode(new Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.add("Item 1").setIcon(R.drawable.ic_launcher).setShowAsAction(MenuItem.SHOW_AS_ACTION_WITH_TEXT | MenuItem.SHOW_AS_ACTION_ALWAYS);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; }
#Override
public void onDestroyActionMode(ActionMode mode) { }
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; }
});
}
}
Does anyone know what I could do to fix it ?
I doubt that you can. "Always" and "with text" are requests, not commands. The framework does not always honor either of them.
Instead of adding this menu item via code try to use this attribute:
android:showAsAction="always|withText"
and add it to the item in the menu.xml

Categories

Resources