Show copy/paste context menu on text using code android - android

I have an EditText and its text gets selected from through code. But I want to allow users to cut/copy the selected text. However, the cut/copy context menu doesn't appear until user long presses on text. But then it loses the actual selection. So, I'm thinking to show the context menu as the text get selected by the code.
I tried this inside onFocusChanged, but nothing appeared.
openContextMenu(EditText);

IF I follow you usecase correctly, you can open context menu from the onFocusChangeListener registered on the testedEditText.
I prepared some small test for that which seems to be correctly supporting your usecase.
You need to openMenu on the hooks which are selecting the content in the EditText.
public class Main extends Activity {
private EditText testedEditText;
private Button selectingButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
selectingButton = (Button) findViewById(R.id.button);
testedEditText = (EditText) findViewById(R.id.textView);
registerForContextMenu(testedEditText);
selectingButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
testedEditText.setSelection(6, 11);
openContextMenu(testedEditText);
}
});
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.cmenu, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.select_all:
return true;
case R.id.copy:
//do something
return true;
case R.id.cut:
//do something
return true;
case R.id.paste:
//do something
return true;
default:
return super.onContextItemSelected(item);
}
}
}
Weirdly enough registering testedEditText.requestFocus(), and setting onFocusChangedListener for EditText was not enough.
Additional xml files for reference:
cmenu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/select_all"
android:title="select all"
/>
<item android:id="#+id/copy"
android:title="copy"
/>
<item android:id="#+id/cut"
android:title="cut"
/>
<item android:id="#+id/paste"
android:title="paste"
/>
</menu>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World, Initial Text..."
android:layout_centerInParent="true"
/>
<Button android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="button"
/>
</RelativeLayout>

Related

Android: Customized menu in toolbar

Currently, I have a spinner menu attached to my toolbar.
toolbar_spinner_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/overview_spinner"
app:actionViewClass="android.widget.Spinner"
app:showAsAction="always"
android:title="" />
</menu>
I inflated the menu in my fragment by calling
AFragment.java
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.toolbar_spinner_menu, menu);
final int[] previousSelection = {0};
final MenuItem item = menu.findItem(R.id.overview_spinner);
final Spinner mSpinner = (Spinner) MenuItemCompat.getActionView(item);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), R.layout.spinner_item, SPINNER_LIST);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(adapter);
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
switch (position) {
case 0: // Recent
break;
case 1: // Now
break;
default:
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
super.onCreateOptionsMenu(menu, inflater);
}
R.layout.spinner_item
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinner_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="#FFFFFF"
android:textStyle="bold"
android:gravity="start" />
When an item is selected from the spinner, the user will be prompted to select a month and year from a dialog box. Upon clicking on "OK", the spinner's text should be updated into the choice made.
But this is what i get when I try to update the text dynamically using the following block of code, and as you can see, the text got cut off.
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
TextView selectedText = (TextView) getActivity().findViewById(R.id.spinner_text);
switch (position) {
case 0: // Recent
selectedText.setText("Since 1/8/2016");
break;
case 1: // Now
What I want to achieve is as following in the image illustration from Citymapper.
Any help rendered will be much appreciated!
I think the problem is with the spinner item width..your textview is getting too much space from the action bar rather than the space available..try lowering the textsize or you can remove the title from action bar as shown in the green one.
Solved the issue by modifying R.layout.spinner_item by changing gravity to start from right and setting a fixed layout_width in addition to some padding so it does not stick too close to the icon.
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinner_text"
android:layout_width="150dp"
android:paddingRight="8dp"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textColor="#FFFFFF"
android:textStyle="bold"
android:gravity="right" />

OnOptionsItemSelected not being called for Action Bar Menu Item with custom actionLayout

I'm trying to implement a notification icon in my actionbar to show the count of notifications. Something like
I've added a custom layout file for it NotificationIcon.xml:
<!-- Menu Item Image -->
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp"
android:clickable="true"
android:src="#drawable/notification" />
<!-- Badge Count -->
<TextView
android:id="#+id/actionbar_notifcation_textview"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:minWidth="20dp"
android:layout_alignParentRight="true"
android:gravity="center_horizontal"
android:background="#drawable/circle_green"
android:fontFamily="sans-serif-black"
android:textStyle="bold"
android:text="0"
android:textColor="#FFFFFF" />
</RelativeLayout>
And used it in my menu as main_activity_actions.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/action_add"
android:title="#string/AddTag"
android:icon="#+drawable/ic_action_new"
android:showAsAction="always" />
<item
android:id="#+id/notification_icon"
android:title="#string/PendingJobs"
android:actionLayout="#layout/notificationIcon"
android:icon="#+drawable/notification"
android:showAsAction="always" />
<item
android:id="#+id/gps_status_icon"
android:title="#string/GPS"
android:icon="#+drawable/gps_grey"
android:showAsAction="always" />
</menu>
The UI looks fine but the OnOptionsItemSelected is not being called for the notification icon. It works fine for the other two.
I did google this and ound this link: onOptionsItemSelected not getting called when using custom action view
I tried to implement it in my main activity:
public override bool OnCreateOptionsMenu(IMenu menu)
{
actionBarMenu = menu;
MenuInflater.Inflate(Resource.Menu.main_activity_actions, menu);
var notificationMenuItem = menu.FindItem(Resource.Id.notification_icon);
notificationMenuItem.ActionView.Click += (sender, args) => {
this.OnOptionsItemSelected(notificationMenuItem);
};
return base.OnCreateOptionsMenu(menu);
}
but it does not works for me. It never fires the click event.
Please help.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
final View notification_icon= menu.findItem(R.id.notification_icon).getActionView();
notification_icon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// write ur code here
}
});
return super.onCreateOptionsMenu(menu);
}
use this code......hope it helps :)
i struggle with the same Problem and found following Solution:
First of all: i really don't know why but if you delete the
android:clickable="true"
then ... and ONLY then you get the click event!!!
Second: you have to set the Listener...
...
item.getActionView().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do Your Stuff.....
}
});
May someone can Explain why this is with the "android:clickable" Thing... i tough the standard value IS true??
You had made ImageButton clickable, and then written the clickListener for the Layout of menuItem. You can observe that if you click outside the ImageButton but inside the MenuItem layout, your listener will work. The reason is simple clickListener for ImageButton has nothing to do, on setting Clickable = true defines whether this button reacts to click events. Just simply set Clickable = false, your button will not react to its click event, eventually your whole layout will react to your defined clickListener and then your problem will be solved.

Action Bar change effect

I'm trying to reproduce the Google Keep, Gmail, etc ActionBar change effects.
Like image bellow, when the user select a note or a mail, the action bar changes using its effects.
I would like to do the same.
Any help?
Looks like it's relatively new ability, called Contextual action mode.
Simply put, it's just specific 'context' menu for long-selected item. I think that the link above provides enough information. However, below is some simple example on how to use it:
main.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:clipChildren="false"
android:id="#+id/root">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button"
android:text="Do Long Press"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:layout_marginTop="5dp" />
</RelativeLayout>
context_menu.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:icon="#android:drawable/ic_menu_close_clear_cancel"
android:title="close"
android:showAsAction="always"
android:id="#+id/close_menu" />
</menu>
MyActivity.java:
public class MyActivity extends Activity implements ActionMode.Callback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.button).setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(final View v) {
startActionMode(MyActivity.this);
return true;
}
});
}
#Override
public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
return true;
}
#Override
public boolean onPrepareActionMode(final ActionMode mode, final Menu menu) {
// TODO: auto-generated block
return false;
}
#Override
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
switch (item.getItemId()) {
case R.id.close_menu:
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(final ActionMode mode) {
// TODO: auto-generated block
}
}
It looks like the following:
Execute Long press
Please note, that V item is default one and in context_menu.xml I've provided only X item.

Android custom dropdown/popup menu

How do I do a custom dropdown/popup menu anchored to a button?
I need it to work like the popup menu (anchored to a view), and do something when I click an item from the menu.
How do I add items to the menu by code, keeping menu's height and make it scrollable if there are more than 5 items. I don't need to add any images, just text.
Update: To create a popup menu in android with Kotlin refer my answer here.
To create a popup menu in android with Java:
Create a layout file activity_main.xml under res/layout directory which contains only one button.
Filename: activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="62dp"
android:layout_marginTop="50dp"
android:text="Show Popup" />
</RelativeLayout>
Create a file popup_menu.xml under res/menu directory
It contains three items as shown below.
Filename: poupup_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/one"
android:title="One"/>
<item
android:id="#+id/two"
android:title="Two"/>
<item
android:id="#+id/three"
android:title="Three"/>
</menu>
MainActivity class which displays the popup menu on button click.
Filename: MainActivity.java
public class MainActivity extends Activity {
private Button button1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Creating the instance of PopupMenu
PopupMenu popup = new PopupMenu(MainActivity.this, button1);
//Inflating the Popup using xml file
popup.getMenuInflater()
.inflate(R.menu.popup_menu, popup.getMenu());
//registering popup with OnMenuItemClickListener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(
MainActivity.this,
"You Clicked : " + item.getTitle(),
Toast.LENGTH_SHORT
).show();
return true;
}
});
popup.show(); //showing popup menu
}
}); //closing the setOnClickListener method
}
}
To add programmatically:
PopupMenu menu = new PopupMenu(this, view);
menu.getMenu().add("One");
menu.getMenu().add("Two");
menu.getMenu().add("Three");
menu.show();
Follow this link for creating menu programmatically.
I know this is an old question, but I've found another answer that worked better for me and it doesn't seem to appear in any of the answers.
Create a layout xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:paddingStart="10dip"
android:paddingEnd="10dip">
<ImageView
android:id="#+id/shoe_select_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:scaleType="fitXY" />
<TextView
android:id="#+id/shoe_select_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="20sp"
android:paddingStart="10dp"
android:paddingEnd="10dp"/>
</LinearLayout>
Create a ListPopupWindow and a map with the content:
ListPopupWindow popupWindow;
List<HashMap<String, Object>> data = new ArrayList<>();
HashMap<String, Object> map = new HashMap<>();
map.put(TITLE, getString(R.string.left));
map.put(ICON, R.drawable.left);
data.add(map);
map = new HashMap<>();
map.put(TITLE, getString(R.string.right));
map.put(ICON, R.drawable.right);
data.add(map);
Then on click, display the menu using this function:
private void showListMenu(final View anchor) {
popupWindow = new ListPopupWindow(this);
ListAdapter adapter = new SimpleAdapter(
this,
data,
R.layout.shoe_select,
new String[] {TITLE, ICON}, // These are just the keys that the data uses (constant strings)
new int[] {R.id.shoe_select_text, R.id.shoe_select_icon}); // The view ids to map the data to
popupWindow.setAnchorView(anchor);
popupWindow.setAdapter(adapter);
popupWindow.setWidth(400);
popupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position){
case 0:
devicesAdapter.setSelectedLeftPosition(devicesList.getChildAdapterPosition(anchor));
break;
case 1:
devicesAdapter.setSelectedRightPosition(devicesList.getChildAdapterPosition(anchor));
break;
default:
break;
}
runOnUiThread(new Runnable() {
#Override
public void run() {
devicesAdapter.notifyDataSetChanged();
}
});
popupWindow.dismiss();
}
});
popupWindow.show();
}
The Kotlin Way
fun showPopupMenu(view: View) {
PopupMenu(view.context, view).apply {
menuInflater.inflate(R.menu.popup_men, menu)
setOnMenuItemClickListener { item ->
Toast.makeText(view.context, "You Clicked : " + item.title, Toast.LENGTH_SHORT).show()
true
}
}.show()
}
UPDATE: In the above code, the apply function returns this which is not required, so we can use run which don't return anything and to make it even simpler we can also remove the curly braces of showPopupMenu method.
Even Simpler:
fun showPopupMenu(view: View) = PopupMenu(view.context, view).run {
menuInflater.inflate(R.menu.popup_men, menu)
setOnMenuItemClickListener { item ->
Toast.makeText(view.context, "You Clicked : ${item.title}", Toast.LENGTH_SHORT).show()
true
}
show()
}
First, create a folder named “menu” in the “res” folder.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/search"
android:icon="#android:drawable/ic_menu_search"
android:title="Search"/>
<item
android:id="#+id/add"
android:icon="#android:drawable/ic_menu_add"
android:title="Add"/>
<item
android:id="#+id/edit"
android:icon="#android:drawable/ic_menu_edit"
android:title="Edit">
<menu>
<item
android:id="#+id/share"
android:icon="#android:drawable/ic_menu_share"
android:title="Share"/>
</menu>
</item>
</menu>
Then, create your Activity Class:
public class PopupMenu1 extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.popup_menu_1);
}
public void onPopupButtonClick(View button) {
PopupMenu popup = new PopupMenu(this, button);
popup.getMenuInflater().inflate(R.menu.popup, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(PopupMenu1.this,
"Clicked popup menu item " + item.getTitle(),
Toast.LENGTH_SHORT).show();
return true;
}
});
popup.show();
}
}

Click on EditText doesn't show softkeyboard

I am using ActionBarSherlock, in the ActionBar i have this custom layout to appear when i click on the searchIcon.
public boolean onCreateOptionsMenu(final Menu menu) {
LayoutInflater inflater = getLayoutInflater();
final View view = inflater.inflate(R.layout.on_search_icon_clicked,null, false);
view.findViewById(R.id.search_image).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View arg0) {
EditText searchET = (EditText) view.findViewById(R.id.search_editText);
String s = searchET.getText().toString();
Toast.makeText(getBaseContext(), "Searching for: " + s,1000).show();
}
});
menu.add("Search")
.setIcon(R.drawable.ic_search)
.setActionView(view)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
return true;
}
on_search_icon_clicked.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/search_image"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:src="#drawable/ic_search"
android:clickable="true"
android:contentDescription="#string/seach_icon" />
<EditText
android:id="#+id/search_editText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/search_image"
android:hint="#string/search"
android:singleLine="true" />
</RelativeLayout>
So, i click on the SearchIcon ---> i get the custom layout with editText and ImageView ---> click on editText, opens softkeyboard ---> enters string and clicks the imageView ---> shows me the toast.
Its fine till here.
The problem is:
i close the softkeyboard using device back button ---> then close the custom layout using ActionBar Home icon click ---> now click the searchIcon again, which reopens the custom layout, with editText filled with previously searched string ---> click on the editText, the softkeyboard doesn't open up (here is the problem).
Please help, i have no idea why its not working as expected.
Thank You
I have faced this problem before and here is my solution
//your_menu
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_search"
android:orderInCategory="0"
android:icon="#drawable/btn_search"
android:title="Search"
android:actionLayout="#layout/on_search_icon_clicked"
android:showAsAction="always|collapseActionView"
/>
</menu>
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getSupportMenuInflater().inflate(R.menu.your_menu, menu);
mSearchbar = (MenuItem) menu.findItem(R.id.menu_search);
View actionview = mSearchbar.getActionView();
mEtSearchbar = ((EditText) actionview.findViewById(R.id.search_editText));
mEtSearchbar.setOnEditorActionListener(this);
mEtSearchbar.addTextChangedListener(this);
super.onCreateOptionsMenu(menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
Intent intent;
switch (item.getItemId())
{
case R.id.menu_search:
mEtSearchbar.clearFocus();
(new Handler()).postDelayed(new Runnable() {
public void run() {
mEtSearchbar.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0));
mEtSearchbar.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP , 0, 0, 0));
}
}, 100);
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
mEtSearchbar ~ your searchET

Categories

Resources