EditText: Disable Paste/Replace menu pop-up on Text Selection Handler click event
Solution: Override isSuggestionsEnabled
and canPaste
in EditText
.
For the quick solution, copy the class below - this class overrides the EditText
class, and blocks all events accordingly.
For the gritty details, keep reading.
The solution lies in preventing PASTE/REPLACE menu from appearing in the show()
method of the (non-documented) android.widget.Editor
class. Before the menu appears, a check is done to if (!canPaste && !canSuggest) return;
. The two methods that are used as the basis to set these variables are both in the EditText
class:
isSuggestionsEnabled()
is public, and may thus be overridden.canPaste()
is not, and thus must be hidden by introducing a function of the same name in the derived class.
So incorporating these updates into a class that also has the setCustomSelectionActionModeCallback, and the disabled long-click, here is the full class to prevent all editing (but still display the text selection handler) for controlling the cursor:
package com.cjbs.widgets;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
/**
* This is a thin veneer over EditText, with copy/paste/spell-check removed.
*/
public class NoMenuEditText extends EditText
{
private final Context context;
/** This is a replacement method for the base TextView class' method of the same name. This
* method is used in hidden class android.widget.Editor to determine whether the PASTE/REPLACE popup
* appears when triggered from the text insertion handle. Returning false forces this window
* to never appear.
* @return false
*/
boolean canPaste()
{
return false;
}
/** This is a replacement method for the base TextView class' method of the same name. This method
* is used in hidden class android.widget.Editor to determine whether the PASTE/REPLACE popup
* appears when triggered from the text insertion handle. Returning false forces this window
* to never appear.
* @return false
*/
@Override
public boolean isSuggestionsEnabled()
{
return false;
}
public NoMenuEditText(Context context)
{
super(context);
this.context = context;
init();
}
public NoMenuEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
this.context = context;
init();
}
public NoMenuEditText(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
this.context = context;
init();
}
private void init()
{
this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
this.setLongClickable(false);
}
/**
* Prevents the action bar (top horizontal bar with cut, copy, paste, etc.) from appearing
* by intercepting the callback that would cause it to be created, and returning false.
*/
private class ActionModeCallbackInterceptor implements ActionMode.Callback
{
private final String TAG = NoMenuEditText.class.getSimpleName();
public boolean onCreateActionMode(ActionMode mode, Menu menu) { return false; }
public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; }
public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; }
public void onDestroyActionMode(ActionMode mode) {}
}
}
I've tested this in Android v4.4.2 and v4.4.3.
How to remove Edit from EditText context menu
How about creating TextView and making use of Clipboard.
TextView mTextView = new TextView(this);
registerForContextMenu(mTextView);
@Override
public boolean onContextItemSelected(MenuItem item) {
((ClipboardManager) getSystemService(CLIPBOARD_SERVICE)).setText(mTextView.getText());
return true;
}
How to Disable Only Cut option From EditText?
First set a customSelectionActionModeCallback.
You could identify the cut option by its id: android.R.id.cut
So your code in the onCreateActionMode from the ActionMode.Callback would look like this:
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuItem menuItem = menu.findItem(android.R.id.cut);
if (menuItem != null) {
menuItem.setVisible(false);
}
return true;
}
Or you could even remove it by using menu.removeItem(android.R.id.cut).
Also null-check for menu.findItem(android.R.id.cut) because it might return null when calling setVisible on it.
Related Topics
Android Studio: Creating Landscape Layouts
Javadoc in Eclipse Failing to Recognize Packages
How to Reference an Asset in a Library Project
Continually Running Background Service
Android Emulator Camera Custom Image
How to Set Soap Header Using Ksoap2 - Android
Classloader Referenced Unknown Path: /Data/App/
How to Disable Facebook Single Sign on for Android - Facebook-Android-Sdk
Android L (API 21) - Java.Lang.Illegalargumentexception: Service Intent Must Be Explicit
How to Draw Border on Just One Side of a Linear Layout
How to Create an Avd for Android 4.0
Reusing Fragments in a Fragmentpageradapter
How to Finish Current Activity in Android
Get Battery Level Before Broadcast Receiver Responds for Intent.Action_Battery_Changed
How to Check the Multiple Permission at Single Request in Android M