I am making a vertical EditText
for traditional Mongolian. I have successfully implemented it by embedding a slightly modified EditText
inside of a
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) {}
}
}