How to disable copy/paste from/to EditText

后端 未结 24 1344
情歌与酒
情歌与酒 2020-11-22 12:18

In my application, there is a registration screen, where i do not want the user to be able to copy/paste text into the EditText field. I have set an onLon

相关标签:
24条回答
  • 2020-11-22 12:41

    Try Following custome class for prevant copy and paste in Edittext

    public class SegoeUiEditText extends AppCompatEditText {
    private final Context context;
    
    
    @Override
    public boolean isSuggestionsEnabled() {
        return false;
    }
    public SegoeUiEditText(Context context) {
        super(context);
        this.context = context;
        init();
    }
    
    public SegoeUiEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }
    
    public SegoeUiEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
        init();
    }
    
    
    private void setFonts(Context context) {
        this.setTypeface(Typeface.createFromAsset(context.getAssets(), "Fonts/Helvetica-Normal.ttf"));
    }
    
    private void init() {
    
            setTextIsSelectable(false);
            this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
            this.setLongClickable(false);
    
    }
    @Override
    public int getSelectionStart() {
    
        for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
            if (element.getMethodName().equals("canPaste")) {
                return -1;
            }
        }
        return super.getSelectionStart();
    }
    /**
     * 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, android.view.ActionMode.Callback {
        private final String TAG = SegoeUiEditText.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) {}
    
        @Override
        public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
            return false;
        }
    
        @Override
        public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
            menu.clear();
            return false;
        }
    
        @Override
        public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
            return false;
        }
    
        @Override
        public void onDestroyActionMode(android.view.ActionMode mode) {
    
        }
    }
    

    }

    0 讨论(0)
  • 2020-11-22 12:43

    here is a best way to disable cut copy paste of editText work in all version

    if (android.os.Build.VERSION.SDK_INT < 11) {
            editText.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
    
                @Override
                public void onCreateContextMenu(ContextMenu menu, View v,
                        ContextMenuInfo menuInfo) {
                    // TODO Auto-generated method stub
                    menu.clear();
                }
            });
        } else {
            editText.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
    
                public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                    // TODO Auto-generated method stub
                    return false;
                }
    
                public void onDestroyActionMode(ActionMode mode) {
                    // TODO Auto-generated method stub
    
                }
    
                public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                    // TODO Auto-generated method stub
                    return false;
                }
    
                public boolean onActionItemClicked(ActionMode mode,
                        MenuItem item) {
                    // TODO Auto-generated method stub
                    return false;
                }
            });
        }
    
    0 讨论(0)
  • 2020-11-22 12:43

    Who is looking for a solution in Kotlin use the below class as a custom widget and use it in the xml.

    class SecureEditText : TextInputEditText {

    /** 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 fun isSuggestionsEnabled(): Boolean {
        return false
    }
    
    override fun getSelectionStart(): Int {
        for (element in Thread.currentThread().stackTrace) {
            if (element.methodName == "canPaste") {
                return -1
            }
        }
        return super.getSelectionStart()
    }
    
    public override fun onSelectionChanged(start: Int, end: Int) {
    
        val text = text
        if (text != null) {
            if (start != text.length || end != text.length) {
                setSelection(text.length, text.length)
                return
            }
        }
    
        super.onSelectionChanged(start, end)
    }
    
    companion object {
        private val EDITTEXT_ATTRIBUTE_COPY_AND_PASTE = "isCopyPasteDisabled"
        private val PACKAGE_NAME = "http://schemas.android.com/apk/res-auto"
    }
    
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        disableCopyAndPaste(context, attrs)
    }
    
    /**
     * Disable Copy and Paste functionality on EditText
     *
     * @param context Context object
     * @param attrs   AttributeSet Object
     */
    private fun disableCopyAndPaste(context: Context, attrs: AttributeSet) {
        val isDisableCopyAndPaste = attrs.getAttributeBooleanValue(
            PACKAGE_NAME,
            EDITTEXT_ATTRIBUTE_COPY_AND_PASTE, true
        )
        if (isDisableCopyAndPaste && !isInEditMode()) {
            val inputMethodManager =
                context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            this.setLongClickable(false)
            this.setOnTouchListener(BlockContextMenuTouchListener(inputMethodManager))
        }
    }
    
    /**
     * Perform Focus Enabling Task to the widget with the help of handler object
     * with some delay
     * @param inputMethodManager is used to show the key board
     */
    private fun performHandlerAction(inputMethodManager: InputMethodManager) {
        val postDelayedIntervalTime: Long = 25
        Handler().postDelayed(Runnable {
            this@SecureEditText.setSelected(true)
            this@SecureEditText.requestFocusFromTouch()
            inputMethodManager.showSoftInput(
                this@SecureEditText,
                InputMethodManager.RESULT_SHOWN
            )
        }, postDelayedIntervalTime)
    }
    
    /**
     * Class to Block Context Menu on double Tap
     * A custom TouchListener is being implemented which will clear out the focus
     * and gain the focus for the EditText, in few milliseconds so the selection
     * will be cleared and hence the copy paste option wil not pop up.
     * the respective EditText should be set with this listener
     *
     * @param inputMethodManager is used to show the key board
     */
    private inner class BlockContextMenuTouchListener internal constructor(private val inputMethodManager: InputMethodManager) :
        View.OnTouchListener {
        private var lastTapTime: Long = 0
        val TIME_INTERVAL_BETWEEN_DOUBLE_TAP = 30
        override fun onTouch(v: View, event: MotionEvent): Boolean {
            if (event.getAction() === MotionEvent.ACTION_DOWN) {
                val currentTapTime = System.currentTimeMillis()
                if (lastTapTime != 0L && currentTapTime - lastTapTime < TIME_INTERVAL_BETWEEN_DOUBLE_TAP) {
                    this@SecureEditText.setSelected(false)
                    performHandlerAction(inputMethodManager)
                    return true
                } else {
                    if (lastTapTime == 0L) {
                        lastTapTime = currentTapTime
                    } else {
                        lastTapTime = 0
                    }
                    performHandlerAction(inputMethodManager)
                    return true
                }
            } else if (event.getAction() === MotionEvent.ACTION_MOVE) {
                this@SecureEditText.setSelected(false)
                performHandlerAction(inputMethodManager)
            }
            return false
        }
    }
    

    }

    0 讨论(0)
  • 2020-11-22 12:44

    In addition to the setCustomSelectionActionModeCallback, and disabled long-click solutions, it's necessary to prevent the PASTE/REPLACE menus from appearing when the text selection handle is clicked, as per the image below:

    Text selection handle with paste menu

    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.

    A more complete answer is available here.

    0 讨论(0)
  • 2020-11-22 12:45

    Kotlin solution:

    fun TextView.disableCopyPaste() {
        isLongClickable = false
        setTextIsSelectable(false)
        customSelectionActionModeCallback = object : ActionMode.Callback {
            override fun onCreateActionMode(mode: ActionMode?, menu: Menu): Boolean {
                return false
            }
    
            override fun onPrepareActionMode(mode: ActionMode?, menu: Menu): Boolean {
                return false
            }
    
            override fun onActionItemClicked(mode: ActionMode?, item: MenuItem): Boolean {
                return false
            }
    
            override fun onDestroyActionMode(mode: ActionMode?) {}
        }
    }
    

    Then you can simply call this method on your TextView:

    override fun onCreate() {
        priceEditText.disableCopyPaste()
    }
    
    0 讨论(0)
  • 2020-11-22 12:45

    i added Extension Function in Kotlin language :

    fun EditText.disableTextSelection() {
        this.setCustomSelectionActionModeCallback(object : android.view.ActionMode.Callback {
            override fun onActionItemClicked(mode: android.view.ActionMode?, item: MenuItem?): Boolean {
                return false
            }
            override fun onCreateActionMode(mode: android.view.ActionMode?, menu: Menu?): Boolean {
                return false
            }
            override fun onPrepareActionMode(mode: android.view.ActionMode?, menu: Menu?): Boolean {
                return false
            }
            override fun onDestroyActionMode(mode: android.view.ActionMode?) {
            }
        })
    }
    

    you can use it like this :

    edit_text.disableTextSelection()
    

    also added below line in your xml :

                    android:longClickable="false"
                    android:textIsSelectable="false"
    
    0 讨论(0)
提交回复
热议问题