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.
or simply just use
yourEditText.setLongClickable(false);
OR in XML
android:longClickable="false"
Update
Actually the user wants to disable the text selection handle itself
1. Create a shape (handle.xml)
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <size android:height="0dp" android:width="0dp" /> </shape>
2. In your EditText
android:textSelectHandle="@drawable/handle"
Here is a hack to disable "paste" popup. You have to override EditText
method:
@Overridepublic int getSelectionStart() { for (StackTraceElement element : Thread.currentThread().getStackTrace()) { if (element.getMethodName().equals("canPaste")) { return -1; } } return super.getSelectionStart();}
This solution works on newer versions of Android as well, unlike the accepted answer.