Disable EditText context menu

前端 未结 7 1260
花落未央
花落未央 2020-11-28 13:54

I am making a vertical EditText for traditional Mongolian. I have successfully implemented it by embedding a slightly modified EditText inside of a

相关标签:
7条回答
  • 2020-11-28 14:39

    I tried all the answers above, but I did not get a complete solution. If you want do disable only the PASTE option, you can try this:

    override fun getSelectionStart(): Int {
        for (element in Thread.currentThread().stackTrace) {
            if (element.methodName == "canPaste") {
                return -1
            }
        }
        return super.getSelectionStart()
    }
    

    It is just a hack, but I didn't find anything better.

    if you want to disable the menu and cursor completely, you can try following class instead of your EditText:

    class MaskedCodeEditTextView : EditText {
        constructor(context: Context) : super(context) {
            init()
            blockContextMenu()
        }
    
        constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
            init()
            blockContextMenu()
        }
    
        constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(
            context,
            attrs,
            defStyle
        ) {
            init()
            blockContextMenu()
        }
    
        override fun getSelectionStart(): Int {
            for (element in Thread.currentThread().stackTrace) {
                if (element.methodName == "canPaste") {
                    return -1
                }
            }
            return super.getSelectionStart()
        }
    
        private fun setInsertionDisabled() {
            try {
                val editorField = TextView::class.java.getDeclaredField("mEditor")
                editorField.isAccessible = true
                val editorObject = editorField[this]
                val editorClass = Class.forName("android.widget.Editor")
                val mInsertionControllerEnabledField =
                    editorClass.getDeclaredField("mInsertionControllerEnabled")
                mInsertionControllerEnabledField.isAccessible = true
                mInsertionControllerEnabledField[editorObject] = false
            } catch (ignored: Exception) {
                // ignore exception here
            }
        }
    
        private fun blockContextMenu() {
            this.customSelectionActionModeCallback = ActionModeCallbackInterceptor()
            this.isLongClickable = false
            setOnClickListener { v: View? ->
                v?.let {
                    if(!it.isFocused) {
                        requestFocus()
                    } else {
                        clearFocus()
                        requestFocus()
                    }
                }
            }
        }
    
        override fun isSuggestionsEnabled(): Boolean {
            return false
        }
    
        private fun init() {
            this.customSelectionActionModeCallback = ActionModeCallbackInterceptor()
            this.isLongClickable = false
        }
    
        override fun onTouchEvent(event: MotionEvent): Boolean {
            if (event.action == MotionEvent.ACTION_DOWN) {
                setInsertionDisabled()
            }
            return super.onTouchEvent(event)
        }
    
        private inner class ActionModeCallbackInterceptor : 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) {}
        }
    }
     
    
    0 讨论(0)
  • 2020-11-28 14:40

    the solution is very simple

    public class MainActivity extends AppCompatActivity {
    
    EditText et_0;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        et_0 = findViewById(R.id.et_0);
    
        et_0.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                //to keep the text selection capability available ( selection cursor)
                return true;
            }
    
            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                //to prevent the menu from appearing
                menu.clear();
                return false;
            }
    
            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                return false;
            }
    
            @Override
            public void onDestroyActionMode(ActionMode mode) {
    
            }
        });
       }
    }
    

    0 讨论(0)
  • 2020-11-28 14:45

    try this

    mEditText.setClickable(false);
    mEditText.setEnabled(false);
    

    UPDATE

    Try this solution by Extending the Edittext,

    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.ActionMode;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.EditText;
    
    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) {}
    }
    }
    

    Reference: https://stackoverflow.com/a/28893714/5870896

    0 讨论(0)
  • 2020-11-28 14:46
    mEditText.setLongClickable(false);
    

    Its the simplest way to disable the edit text.

    0 讨论(0)
  • 2020-11-28 14:47

    This is how you block the copy paste menu from appearing in any way, shape or form. This bug really drove me crazy, and as with any Samsung bug you know its in their code but you also know they won't fix it any time soon. Anyways, here's wonder wall...

    1. Check if Android.Build.Model.toLowerCase().startsWith('sm-g930'). Do not match the whole string, the last letter is a minor version identifier. I stored this boolean in shouldBlockCopyPaste variable which comes up later.

    2. If it matches you want to block the copy paste menu from showing. This is how you ACTUALLY DO IT!!!

    Override these 2 functions, you'll notice my shouldBlockCopyPaste boolean, this is so other devices dont get blocked.

       @Override
       public ActionMode StartActionMode (ActionMode.Callback callback){
          if (shouldBlockCopyPaste) {
            return null;
          } else {
            return super.StartActionMode(callback);
          }
        }
    
       @Override
       public ActionMode StartActionMode (ActionMode.Callback callback, int type){
          if (shouldBlockCopyPaste) {
            return null;
          } else {
            return super.StartActionMode(callback, type);
          }
        }
    
    0 讨论(0)
  • 2020-11-28 14:51

    I have made this code for EditText, and it worked fine for such an issue.

    try {
        edtName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                edtName.setSelection(0);
            }
        });
        edtName.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return true;
            }
        });
        edtName.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
            @Override
            public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { return false; }
            @Override
            public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) { return false; }
            @Override
            public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) { return false; }
            @Override
            public void onDestroyActionMode(ActionMode actionMode) { }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }
    
    0 讨论(0)
提交回复
热议问题