最近项目要求屏蔽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 EditText长按屏蔽ActionMode context菜单但保留选择工具功能的更多相关文章

  1. Android ListView 长按列表弹出菜单

    Android ListView 长按列表弹出菜单 设置长按菜单 listView.setOnCreateContextMenuListener(new View.OnCreateContextMen ...

  2. Android — 长按ListView 利用上下文菜单(ActionMode) 进行批量事件处理

    好久没写博客拉``````` 近期最终略微闲一点了``````` 无聊拿手机清理短信.发现批量事件的处理还是挺管用的`````` 那么自己也来山寨一记看看效果吧````` 闲话少说,首先,我们来看下手 ...

  3. 【转】 Pro Android学习笔记(三二):Menu(3):Context菜单

    目录(?)[-] 什么是Context menu 注册View带有Context menu 填Context菜单内容 Context菜单点击触发 什么是Context menu 在桌面电脑,我们都很熟 ...

  4. Android Contextual Menus之一:floating context menu

    Android Contextual Menus之一:floating context menu 上下文菜单 上下文相关的菜单(contextual menu)用来提供影响UI中特定item或者con ...

  5. [Android] TextView长按复制实现方法小结(转载)

    这是别人写的,既然别人总结过了,那我就不花时间研究这个了,但往后会补充一些使用经验之类的 原文地址:http://blog.csdn.net/stzy00/article/details/414778 ...

  6. Android EditText属性

    1.EditText输入的文字为密码形式的设置 (1)通过.xml里设置: 把该EditText设为:android:password="true" // 以”.”形式显示文本 ( ...

  7. [转]Android TCP长连接 心跳机制及实现

    背景知识 智能手机上的长连接心跳和在Internet上的长连接心跳有什么不同 Android系统的推送和iOS的推送有什么区别 几种推送的实现方式 协议 1XMPP简介 2 MQTT简介 3移动端消息 ...

  8. Android EditText悬浮在输入法之上

    Android EditText悬浮在输入法之上 使用 android:windowSoftInputMode="adjustResize" 会让界面整体被顶上去,很多时候我们不需 ...

  9. 71.Android之长连接实现

    转载:http://blog.csdn.net/qq_23547831/article/details/51690047 本文中我们将讲解一下App的长连接实现.一般而言长连接已经是App的标配了,推 ...

随机推荐

  1. 理解tornado

    计算密集型:多进程 IO密集型:多线程   能产生IO阻塞的情况很多,比如网络通讯.磁盘读写.当发生阻塞时,CPU是闲置的,此时如果就一个线程就没法处理其他事情了. 所以对于含有IO阻塞的环境,多线程 ...

  2. Delphi调用约定

    Register Calling Convention Ojbect Pascal的默认调用约定为register,寄存器调用约定会将前三个参数依次放入eax,edx,ecx,返回值是eax(根据类型 ...

  3. [LeetCode] Subsets (bfs的vector实现)

    Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be ...

  4. magento csv导入

  5. Boolean强制转换

    数据类型 转换为true的值 转换为false的值 Boolean true false String 任何非空字符串 空字符串 Number 任何非0数字值(包括无穷大) 0和NaN Object ...

  6. Selenium2学习-002-Selenium2 Web 元素定位及 XPath 编写演示示例

    此文主要对 Selenium2 的 Web 元素定位及 XPath 编写示例,敬请各位亲们参阅,共同探讨.若有不足之处,敬请各位大神指正,不胜感激! 通过 Firefox(火狐)浏览器的插件 Fire ...

  7. JSON.stringify实例应用—将对象转换成JSON类型进行AJAX异步传值

    在上一篇中,对JSON.stringify()方法有了初步的认识,并且做了一些简单的例子.本篇将进一步将JSON.stringify用在复杂些的实例中,例如如下需求: 在进jQuery AJAX异步传 ...

  8. 输出Java的GC信息

    -verbose:gc -XX:+printGC 可以打印GC的简要信息 [GC 4790K->374K(15872K), 0.0001606 secs] [GC 4790K->374K( ...

  9. php自定义错误处理和try{}catch(){}学习

    <?php //语法错误 //运行时的错误 //逻辑错误 //php的错误报告级别 // display_errors; // ini_set("display_errors" ...

  10. Hand 3D Pose Estimation

    https://cvarlab.icg.tugraz.at/projects/hand_detection/