天天看點

android EditText長按屏蔽ActionMode context菜單但保留選擇工具功能

最近項目要求屏蔽EditText 長按出來的ActionMode菜單,但是要保留選擇文本功能。這個屏蔽百度會出現各種方法,這裡說一下我的思路:

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

以上方式經過測試可以取消 editText長按彈出的上下文菜單,但是同時選擇文本的工具也不能用了,這個百度了很久沒找到答案(有的說重寫onTouchEvent方法在裡邊自己實作選擇文本功能,我試了1.實作麻煩 2使用者體驗不好檢視源碼可以看到裡邊有很多東西的)是以決定看看源碼看看goole是怎麼實作actionMode菜單的。

2.調用顯示系統的選擇文字工具 

摸索了很久,先從editText.setCustomSelectionActionModeCallback方法下手既然傳回false就能不顯示上下文菜單,那從這裡入手應該是最直接的。通過查找發現這個方法在父類 TextView中,

可以看到actionModeCallback是指派給了mEditor變量,好了去找這個mEditor變量吧,找到發現mEditor的類型是Editor類,好家夥Editor類在Eclipse中死活找不到幹脆搜源碼吧,搜尋Editor.java關鍵字找到了android.widget.Editor類,就在同一個包下不過是隐藏的類找個類後查找變量mCustomSelectionActionModeCallback 可以看到關鍵的地方了

原來google做了判斷,你要是屏蔽了menu就不顯示選擇工具了,難怪,那我想顯示就隻能自己手動調用getSelectionController().show();方法了,怎麼調用?反射這是java的大招啊,利用反射試試

反射總結起來就是(個人了解):class.getDeclaredField(“mEditor”)//查找變量, 

Class.getDeclaredMethod(“getSelectionController”)//查找方法, 

拿到變量裡的值/指派給變量就是:Field.get(持有者對象) ,Field.set(持有者對象,value); 

方法調用就是Object resultObject=Method.invoke(持有者對象,params), 掌握這幾點一般的使用應該沒啥大問題 

通過反射調用getSelectionController().show();的确可以顯示選擇文本控制工具了,但是有個問題需要輕按兩下才能顯示,長按隻有touchup就不顯了猜想應該是touchup事件觸發了某些東西,最初的猜想是因為屏蔽了actionMod顯示是以肯定還有地方檢察了actionMod菜單是否存在順着這個思路去查找 

首先查找SelectionActionModeCallback類看哪裡執行個體化了它,

看到是指派給了mSelectionActionMode變量了,繼續查找發現了一個stopSelectionActionMode()方法,這個停止肯定會隐藏選擇工具,繼續查找看看那裡調用了stopSelectionActionMode()方法,找到很多但是聯系到長按能顯示選擇工具擡起就馬上隐藏了可以聯想到最有可能的方法 public boolean performLongClick(boolean handled);看到傳進來的參數handled可以影響到stopSelectionActionMode();是否執行好了再看看那裡調用了performLongClick方法

發現在Editor類中找不到了那肯定是擁有Editor的類TextView調用了,進去查找發現TextView中也有一個performLongClick方法

看到給mEditor的mDiscardNextActionUp指派為true了,明顯長按的某種情況是放棄了ActionUp的事件處理,猜想極有可能手動把mDiscardNextActionUp指派為true就可以了嘗試一下

發現果然OK ,這樣實作了屏蔽EditText長按彈出的actionMode菜單,又保留的選擇文字的選擇工具。