自定义文本选择菜单

Android官方控件中,EditText中的文字默认长按呼出文本选择菜单,而TextView需要设置android:textIsSelectable=”true”。

在开发中,如果我们需要自己处理文本菜单的事件,在6.0以下版本中,我们可以自定义TextView或EditText,重onTextContextMenuItem(int id)方法,根据id做相应的处理。在6.0以下版本中,文本菜单按钮大部分只有全选、复制、剪切、粘贴。

注意事项:
1.在我们操作完菜单按钮后,可能菜单按钮和文字选中的样式,都没有回复到原状态。查看源码:
/**
* @hide
*/
protected void stopTextActionMode() {
if (mEditor != null) {
mEditor.stopTextActionMode();
}
}

尝试过想用反射获取Editor类,调用StopTextActionMode()消除菜单和选中样式,但是Editor是系统类,不能导入,所以失败。经过多次查找,最后是给控件重新赋值:setText(getText());解决的。

》在高版本中可能有其他的按钮,可能有些按钮我们用不上,不想让他们显示。我们可以自定以文本选择菜单。只需要为TextView或者EditText设置setCustomSelectionActionModeCallback(ActionMode.Callback callBack)方法,并且在方法里实现ActionMode.Callback()或ActionMode.Callback2()接口。ActionMode.Callback()和ActionMode.Callback2()接口的主要内容相同,只是Callback2中多了一个onGetContentRect()方法,重写可以改变弹出菜单的位置。另外,Callback2需要判断sdk23及以上版本,Callback()不用,但是在6.0以下系统中实际是无效的。

》我们先在res下的menu文件夹里新建一个菜单文件,我把它命名为edit_menu.xml,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/select_all" android:title="全选"/>
    <item android:id="@+id/select_copy" android:title="复制"/>
    <item android:id="@+id/select_cut" android:title="剪切"/>
    <item android:id="@+id/select_paste" android:title="粘贴"/>
</menu>

然后我们完成文本选择菜单的修改

 private class MyActionModeCallback implements ActionMode.Callback {
        private Menu mMenu;

        @Override
        public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
            MenuInflater menuInflater = actionMode.getMenuInflater();
            menu.clear();
            menuInflater.inflate(R.menu.edit_menu, menu);
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
            //菜单创建完成以后获取到其对象,便于后续操作
            this.mMenu = menu;
            return true;
        }

        @Override
        public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
            final int min = getSelectMin();
            final int max = getSelectMax();
            switch (menuItem.getItemId()) {
                case R.id.select_all:
                    //全选
                    selectAll();
                    Toast.makeText(getContext(), "完成全选", Toast.LENGTH_SHORT).show();
                    break;
                case R.id.select_copy:
                    setPrivateClip(getTransformedText(min, max));
                    stopTextActionMode();
                    //setText(selectText)是为了后面的this.mMenu.close()起作用
                    Toast.makeText(getContext(), "选中的内容已复制到剪切板 + copy", Toast.LENGTH_SHORT).show();
                    this.mMenu.close();
                    break;
                case R.id.select_cut:
                    //剪切
                    setPrivateClip(getTransformedText(min, max));
                    deleteText_internal(min, max);
                    Toast.makeText(getContext(), "选中的内容已剪切到剪切板 + cut", Toast.LENGTH_SHORT).show();
                    this.mMenu.close();
                    break;

                case R.id.select_paste:
                    //获取剪切班管理者
                    normalPaste(min , max , true);
                    this.mMenu.close();
                    Toast.makeText(getContext(), "粘贴完成 + paste", Toast.LENGTH_SHORT).show();
                    break;
            }
            return true;
        }

        @Override
        public void onDestroyActionMode(ActionMode actionMode) {

        }
    }

上面这样写的话会有系统的“复制”、“全选”、“搜索”等item,以及其他APP提供的操作item,如果你(或者你们产品经理)傲娇的想要屏蔽所有非本APP自定义item,可以改成这样:

 @Override
 public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
            return true;
        }

 @Override
 public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
       //菜单创建完成以后获取到其对象,便于后续操作
        this.mMenu = menu;
        MenuInflater menuInflater = actionMode.getMenuInflater();
        menu.clear();
        menuInflater.inflate(R.menu.edit_menu, menu);
        return true;
        }

EditText在还有一个插入操作菜单可以设置:

edittext.setCustomInsertionActionModeCallback(textSelectionActionModeCallback);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值