方式一:
设置handle的size为0,这种方式对原生的系统有效,对国产room无效
<?xml version="1.0" encoding="UTF-8"?><shape xmlns:android="/apk/res/android"android:shape="rectangle"><size android:height="0dp"android:width="0dp"/></shape><TextViewandroid:textSelectHandle="@drawable/select_handle"android:textSelectHandleLeft="@drawable/select_handle"android:textSelectHandleRight="@drawable/select_handle"/>
方式二:
EditText中的文字默认长按呼出文本选择菜单,而TextView需要设置android:textIsSelectable=”true”。长按时会呼出菜单,可以设置
setLongClickable(false);
修改文本选择菜单内容,只需要为TextView或者EditText设置setCustomSelectionActionModeCallback()方法,并且在方法里实现ActionMode.Callback()或ActionMode.Callback2()接口。
setLongClickable(false);setTextIsSelectable(false);setCustomSelectionActionModeCallback(new ActionMode.Callback() {@Overridepublic boolean onCreateActionMode(ActionMode mode, Menu menu) {return false;}@Overridepublic boolean onPrepareActionMode(ActionMode mode, Menu menu) {return false;}@Overridepublic boolean onActionItemClicked(ActionMode mode, MenuItem item) {return false;}@Overridepublic void onDestroyActionMode(ActionMode mode) {}});
经过测试这种方式对原生系统或者部分国产机有效(oppo有效,部分华为有效,小米无效)
方式三:反射调用Handle hide相关函数,对全部机型有效。
在TextView的Editor中有下面一段代码
if (!mInsertionControllerEnabled) {hideInsertionPointCursorController();if (mInsertionPointCursorController != null) {mInsertionPointCursorController.onDetached();mInsertionPointCursorController = null;}}if (!mSelectionControllerEnabled) {stopTextActionMode();if (mSelectionModifierCursorController != null) {mSelectionModifierCursorController.onDetached();mSelectionModifierCursorController = null;}}
尝试设置mInsertionControllerEnabled = false 和 mSelectionControllerEnabled = false,来达到屏蔽文本选择菜单效果。
测试发现,MIUI在按下时,都会创建mInsertionPointCursorController和mSelectionModifierCursorController,并且显示select handle,也就是那个讨厌的捶捶。每次按下后,这两个变量又变成true。
既然MIUI要显示,那我们可以在它显示完成后隐藏,就可以屏蔽了,按照这个思路,在TextView的onTouchEvent中,调用hide();
@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:postDelayed(new Runnable() {@Overridepublic void run() {setSelectHandleDisabled();}}, 50); // 延迟50ms,等room显示handle完后,再隐藏break;default:break;}return super.onTouchEvent(event);}
private void setSelectHandleDisabled() {try {Field mEditor = TextView.class.getDeclaredField("mEditor");mEditor.setAccessible(true);Object object = mEditor.get(this);Class mClass = Class.forName("android.widget.Editor");// 选中时handleMethod selectionController = mClass.getDeclaredMethod("getSelectionController");selectionController.setAccessible(true);Object invokeSelect = selectionController.invoke(object);Method hideSelect = invokeSelect.getClass().getDeclaredMethod("hide");hideSelect.invoke(invokeSelect);// 插入时handleMethod insertionController = mClass.getDeclaredMethod("getInsertionController");insertionController.setAccessible(true);Object invokeInsert = insertionController.invoke(object);Method hideInsert = invokeInsert.getClass().getDeclaredMethod("hide");hideInsert.invoke(invokeInsert);} catch (Exception e) {}}