android EditText长按屏蔽ActionMode context菜单但保留选择工具功能

简介: 最近项目要求屏蔽EditText 长按出来的ActionMode菜单,但是要保留选择文本功能。这个屏蔽百度会出现各种方法,这里说一下我的思路: 1.屏蔽百度可知setCustomSelectionActionModeCallback即可, editTextExt.

最近项目要求屏蔽EditText 长按出来的ActionMode菜单,但是要保留选择文本功能。这个屏蔽百度会出现各种方法,这里说一下我的思路:

1.屏蔽百度可知setCustomSelectionActionModeCallback即可,

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">editTextExt.setCustomSelectionActionModeCallback(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Callback() { 
            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onPrepareActionMode</span>(ActionMode mode, Menu menu) { 
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
            } 
            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onDestroyActionMode</span>(ActionMode mode) {  
            } 
            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onCreateActionMode</span>(ActionMode mode, Menu menu) { 
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这里可以添加自己的菜单选项(前提是要返回true的)</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//返回false 就是屏蔽ActionMode菜单</span>
            } 
            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onActionItemClicked</span>(ActionMode mode, MenuItem item) { 
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
            }
        })</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul>

以上方式经过测试可以取消 editText长按弹出的上下文菜单,但是同时选择文本的工具也不能用了,这个百度了很久没找到答案(有的说重写onTouchEvent方法在里边自己实现选择文本功能,我试了1.实现麻烦 2用户体验不好查看源码可以看到里边有很多东西的)所以决定看看源码看看goole是怎么实现actionMode菜单的。

2.调用显示系统的选择文字工具 
摸索了很久,先从editText.setCustomSelectionActionModeCallback方法下手既然返回false就能不显示上下文菜单,那从这里入手应该是最直接的。通过查找发现这个方法在父类 TextView中,

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setCustomSelectionActionModeCallback</span>(ActionMode.Callback actionModeCallback) {
        createEditorIfNeeded();
        mEditor.mCustomSelectionActionModeCallback = actionModeCallback;
    }  </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

可以看到actionModeCallback是赋值给了mEditor变量,好了去找这个mEditor变量吧,找到发现mEditor的类型是Editor类,好家伙Editor类在Eclipse中死活找不到干脆搜源码吧,搜索Editor.java关键字找到了android.widget.Editor类,就在同一个包下不过是隐藏的类找个类后查找变量mCustomSelectionActionModeCallback 可以看到关键的地方了

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * An ActionMode Callback class that is used to provide actions while in text selection mode.
     *
     * The default callback provides a subset of Select All, Cut, Copy and Paste actions, depending
     * on which of these this TextView supports.
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">SelectionActionModeCallback</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ActionMode</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Callback</span> {</span>

        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onCreateActionMode</span>(ActionMode mode, Menu menu) {
            TypedArray styledAttributes = mTextView.getContext().obtainStyledAttributes(
                    com.android.internal.R.styleable.SelectionModeDrawables);

            mode.setTitle(mTextView.getContext().getString(
                    com.android.internal.R.string.textSelectionCABTitle));
            mode.setSubtitle(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>);
            mode.setTitleOptionalHint(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这里定义了全选item,由于篇幅我删了(拷贝 剪切 粘贴等)</span>
            menu.add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, TextView.ID_SELECT_ALL, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, com.android.internal.R.string.selectAll).
                    setIcon(styledAttributes.getResourceId(
                            R.styleable.SelectionModeDrawables_actionModeSelectAllDrawable, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)).
                    setAlphabeticShortcut(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'a'</span>).
                    setShowAsAction(
                            MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);

            styledAttributes.recycle();

            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mCustomSelectionActionModeCallback != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!mCustomSelectionActionModeCallback.onCreateActionMode(mode, menu)) {
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// The custom mode can choose to cancel the action mode</span>
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这里的注释说的很清楚了 放回false就能cancel the action mode</span>
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
                }
            }
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//关键是这里 如果不显示menu则SelectionController就不显示,找到问题的关键了就是它</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (menu.hasVisibleItems() || mode.getCustomView() != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
                getSelectionController().show();
                mTextView.setHasTransientState(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
            }
        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li></ul>

原来google做了判断,你要是屏蔽了menu就不显示选择工具了,难怪,那我想显示就只能自己手动调用getSelectionController().show();方法了,怎么调用?反射这是java的大招啊,利用反射试试

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">@Override
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> boolean <span class="hljs-title" style="box-sizing: border-box;">onCreateActionMode</span>(ActionMode mode, Menu menu) { 
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
                      Field mEditor = TextView.class.getDeclaredField(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"mEditor"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//找到 TextView中的成员变量mEditor  </span>
                      mEditor.setAccessible(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); 
                      Object <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span>= mEditor.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">get</span>(editTextExt);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//根具持有对象拿到mEditor变量里的值 (android.widget.Editor类的实例)</span>
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//--------------------显示选择控制工具------------------------------//</span>
                         Class mClass=Class.forName(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"android.widget.Editor"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//拿到隐藏类Editor; </span>
                         Method  method=mClass.getDeclaredMethod(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"getSelectionController"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//取得方法  getSelectionController </span>
                         method.setAccessible(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//取消访问私有方法的合法性检查     </span>
                         Object resultobject=method.invoke(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//调用方法,返回SelectionModifierCursorController类的实例</span>

                         Method show=resultobject.getClass().getDeclaredMethod(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"show"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//查找 SelectionModifierCursorController类中的show方法</span>
                         show.invoke(resultobject);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//执行SelectionModifierCursorController类的实例的show方法</span>
                         editTextExt.setHasTransientState(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);  

                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) { 
                    e.printStackTrace();
                }
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//return false 隐藏actionMod菜单</span>
            }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>

反射总结起来就是(个人理解):class.getDeclaredField(“mEditor”)//查找变量, 
Class.getDeclaredMethod(“getSelectionController”)//查找方法, 
拿到变量里的值/赋值给变量就是:Field.get(持有者对象) ,Field.set(持有者对象,value); 
方法调用就是Object resultObject=Method.invoke(持有者对象,params), 掌握这几点一般的使用应该没啥大问题 
通过反射调用getSelectionController().show();的确可以显示选择文本控制工具了,但是有个问题需要双击才能显示,长按只有touchup就不显了猜想应该是touchup事件触发了某些东西,最初的猜想是因为屏蔽了actionMod显示所以肯定还有地方检察了actionMod菜单是否存在顺着这个思路去查找 
首先查找SelectionActionModeCallback类看哪里实例化了它,

<code class="hljs sql has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">// <span class="hljs-operator" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Do</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">not</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">start</span> the <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">action</span> mode <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">when</span> extracted text will <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">show</span> up <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">full</span> screen, which would
        // immediately hide the newly created <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">action</span> bar <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">and</span> would be visually distracting.
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!willExtract) {
            ActionMode.Callback actionModeCallback = new SelectionActionModeCallback();</span>
            mSelectionActionMode = mTextView.startActionMode(actionModeCallback);
        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

看到是赋值给了mSelectionActionMode变量了,继续查找发现了一个stopSelectionActionMode()方法,这个停止肯定会隐藏选择工具,继续查找看看那里调用了stopSelectionActionMode()方法,找到很多但是联系到长按能显示选择工具抬起就马上隐藏了可以联想到最有可能的方法 public boolean performLongClick(boolean handled);看到传进来的参数handled可以影响到stopSelectionActionMode();是否执行好了再看看那里调用了performLongClick方法 发现在Editor类中找不到了那肯定是拥有Editor的类TextView调用了,进去查找发现TextView中也有一个performLongClick方法

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">performLongClick</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> handled = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; 
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.performLongClick()) {
            handled = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
        } 
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mEditor != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
            handled |= mEditor.performLongClick(handled);
        } 
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (handled) { performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mEditor != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) mEditor.mDiscardNextActionUp = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// mEditor.mDiscardNextActionUp关键的一句</span>
        } 
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> handled;
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>

看到给mEditor的mDiscardNextActionUp赋值为true了,明显长按的某种情况是放弃了ActionUp的事件处理,猜想极有可能手动把mDiscardNextActionUp赋值为true就可以了尝试一下

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">@Override
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> boolean <span class="hljs-title" style="box-sizing: border-box;">onCreateActionMode</span>(ActionMode mode, Menu menu) { 
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
                      Field mEditor = TextView.class.getDeclaredField(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"mEditor"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//找到 TextView中的成员变量mEditor  </span>
                      mEditor.setAccessible(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); 
                      Object <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span>= mEditor.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">get</span>(editTextExt);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//根具持有对象拿到mEditor变量里的值 (android.widget.Editor类的实例)</span>
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//--------------------显示选择控制工具------------------------------//</span>
                         Class mClass=Class.forName(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"android.widget.Editor"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//拿到隐藏类Editor; </span>
                         Method  method=mClass.getDeclaredMethod(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"getSelectionController"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//取得方法  getSelectionController </span>
                         method.setAccessible(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//取消访问私有方法的合法性检查     </span>
                         Object resultobject=method.invoke(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//调用方法,返回SelectionModifierCursorController类的实例</span>

                         Method show=resultobject.getClass().getDeclaredMethod(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"show"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//查找 SelectionModifierCursorController类中的show方法</span>
                         show.invoke(resultobject);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//执行SelectionModifierCursorController类的实例的show方法</span>
                         editTextExt.setHasTransientState(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); 

                         <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//--------------------忽略最后一次TouchUP事件-----------------------------------------------//</span>
                         Field  mSelectionActionMode=mClass.getDeclaredField(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"mDiscardNextActionUp"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//查找变量Editor类中mDiscardNextActionUp</span>
                         mSelectionActionMode.setAccessible(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); 
                         mSelectionActionMode.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//赋值为true </span>

                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) { 
                    e.printStackTrace();
                }
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//return false 隐藏actionMod菜单</span>
            }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul>

发现果然OK ,这样实现了屏蔽EditText长按弹出的actionMode菜单,又保留的选择文字的选择工具。

相关文章
|
数据库 Android开发
Android使用EditText+Listview实现搜索效果(使用room模糊查询)
本文介绍如何在Android中使用EditText与ListView实现搜索功能,并结合Room数据库完成模糊查询。主要内容包括:Room的模糊查询语句(使用`||`代替`+`号)、布局美化(如去除ListView分割线和EditText下划线)、EditText回车事件监听,以及查询逻辑代码示例。此外,还提供了相关扩展文章链接,帮助读者深入了解ListView优化、动态搜索及Room基础操作。
787 65
|
JavaScript 前端开发 Android开发
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
621 13
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
9月前
|
存储 消息中间件 人工智能
【04】AI辅助编程完整的安卓二次商业实战-寻找修改替换新UI首页图标-菜单图标-消息列表图标-优雅草伊凡
【04】AI辅助编程完整的安卓二次商业实战-寻找修改替换新UI首页图标-菜单图标-消息列表图标-优雅草伊凡
568 4
|
11月前
|
存储 Android开发 数据安全/隐私保护
Thanox安卓系统增加工具下载,管理、阻止、限制后台每个APP运行情况
Thanox是一款Android系统管理工具,专注于权限、后台启动及运行管理。支持应用冻结、系统优化、UI自定义和模块管理,基于Xposed框架开发,安全可靠且开源免费,兼容Android 6.0及以上版本。
1365 4
|
11月前
|
监控 Android开发 数据安全/隐私保护
批量发送短信的平台,安卓群发短信工具插件脚本,批量群发短信软件【autojs版】
这个Auto.js脚本实现了完整的批量短信发送功能,包含联系人管理、短信内容编辑、发送状态监控等功能
|
Java API Android开发
Android实现EditText的抖动效果
本文介绍Android开发中的**samples**资源,适合初学者学习。文中的动画效果源自samples(如API Demos展示)。通过调用`AnimationUtils.loadAnimation`实现摇晃动画,核心代码包括Java文件调用、shake.xml定义水平位移及cycle_7.xml设置循环次数。欢迎留言交流!
184 2
|
11月前
|
API 开发工具 Android开发
qq虚拟视频插件下载安装手机版, 安卓虚拟视频插件,替换摄像头工具
Xposed入口模块:拦截目标应用的相机调用‌23 Camera1 API处理:通过PreviewCallback替换视频流‌1 Camera2 API适
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
658 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
数据采集 JavaScript Android开发
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
696 7
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码android版环境配置流程及功能明细
部署需基于 CentOS 7.9 系统,硬盘不低于 40G,使用宝塔面板安装环境,包括 PHP 7.3(含 Redis、Fileinfo 扩展)、Nginx、MySQL 5.6、Redis 和最新 Composer。Swoole 扩展需按步骤配置。2021.08.05 后部署需将站点目录设为 public 并用 ThinkPHP 伪静态。开发环境建议 Windows 操作系统与最新 Android Studio,基础配置涉及 APP 名称修改、接口域名更换、包名调整及第三方登录分享(如 QQ、微信)的配置,同时需完成阿里云与腾讯云相关设置。

热门文章

最新文章