android TextView屏蔽复制粘贴文本选择菜单

方式一:
设置handle的size为0,这种方式对原生的系统有效,对国产room无效


<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <size
            android:height="0dp"
            android:width="0dp"/>

shape>


<TextView
                android: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() {
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                return false;
            }

            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false;
            }

            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                return false;
            }

            @Override
            public 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();


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                postDelayed(new Runnable() {
                    @Override
                    public 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");
           // 选中时handle
            Method selectionController = mClass.getDeclaredMethod("getSelectionController");
            selectionController.setAccessible(true);
            Object invokeSelect = selectionController.invoke(object);
            Method hideSelect = invokeSelect.getClass().getDeclaredMethod("hide");
            hideSelect.invoke(invokeSelect);
           // 插入时handle
            Method insertionController = mClass.getDeclaredMethod("getInsertionController");
            insertionController.setAccessible(true);
            Object invokeInsert = insertionController.invoke(object);
            Method hideInsert = invokeInsert.getClass().getDeclaredMethod("hide");
            hideInsert.invoke(invokeInsert);
        } catch (Exception e) {

        }

    }

你可能感兴趣的:(android)