問題描述
我的目標是擁有一個沒有花哨功能的 EditText
,只是用于更輕松地移動光標的文本選擇處理程序——因此沒有上下文菜單或彈出窗口.
根據 類,并相應地阻止所有事件.
有關堅韌不拔的細節,請繼續閱讀.
解決辦法在于防止PASTE/REPLACE菜單出現在show()
方法的(未記錄)android.widget.Editor
類.在菜單出現之前,會檢查 if (!canPaste && !canSuggest) return;
.作為設置這些變量的基礎的兩個方法都在 EditText
類中:
isSuggestionsEnabled()
是 public,因此可能會被覆蓋.canPaste()
不是,因此必須被 在派生類中引入同名函數.
因此,將這些更新合并到一個類中,該類也具有 setCustomSelectionActionModeCallback 和 禁用長按,這里是防止所有編輯的完整類(但仍然顯示文本選擇處理程序) 用于控制光標:
包 com.cjbs.widgets;導入android.content.Context;導入android.util.AttributeSet;導入android.view.ActionMode;導入 android.view.Menu;導入android.view.MenuItem;導入 android.widget.EditText;/*** 這是 EditText 上的薄薄的一層,刪除了復制/粘貼/拼寫檢查.*/公共類 NoMenuEditText 擴展 EditText{私有最終上下文上下文;/** 這是基本 TextView 類的同名方法的替換方法.這* 在隱藏類android.widget.Editor中使用方法來判斷PASTE/REPLACE是否彈出* 從文本插入句柄觸發時出現.返回 false 強制此窗口*永遠不會出現.* @return 假*/布爾值 canPaste(){返回假;}/** 這是基本 TextView 類的同名方法的替換方法.這種方法* 用于隱藏類android.widget.Editor 判斷PASTE/REPLACE 是否彈出* 從文本插入句柄觸發時出現.返回 false 強制此窗口*永遠不會出現.* @return 假*/@覆蓋公共布爾 isSuggestionsEnabled(){返回假;}公共 NoMenuEditText(上下文上下文){超級(上下文);this.context = 上下文;在里面();}public NoMenuEditText(上下文上下文,AttributeSet attrs){超級(上下文,屬性);this.context = 上下文;在里面();}public NoMenuEditText(上下文上下文,AttributeSet attrs,int defStyle){超級(上下文,屬性,defStyle);this.context = 上下文;在里面();}私人無效初始化(){this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());this.setLongClickable(false);}/*** 防止出現操作欄(帶有剪切、復制、粘貼等的頂部水平欄)* 通過攔截將導致它被創建的回調,并返回 false.*/私有類 ActionModeCallbackInterceptor 實現 ActionMode.Callback{private final String TAG = NoMenuEditText.class.getSimpleName();public boolean onCreateActionMode(ActionMode mode, Menu menu) { return false;}public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false;}public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false;}公共無效 onDestroyActionMode(ActionMode 模式) {}}}
我已經在 Android v4.4.2 和 v4.4.3 中對此進行了測試.
My goal is to have an EditText
that has no fancy features, just the Text Selection Handler for moving the cursor more easily -- so no context menus or pop-ups.
I've disabled the appearance of the text editing function actionbar (copy/Paste etc.) by consuming the ActionMode Callback event, as per this solution.
The middle Middle Text Select Handle (see image below) still appears when text exists in the field and a click occurs within the text. Great! I want to keep this behaviour. What I DON'T want is the "PASTE" menu to appear when the Text Select Handle itself is clicked.
I have also disabled long-click input for the EditText by setting android:longClickable="false"
in the styles XML. Disabling the long click prevents the "Paste/Replace" menu from appearing when the mouse is clicked and held (i.e. long touch), however when the mouse is clicked (single touch) within the text, the text selection handle appears, and when the text selection handle itself is clicked, then the "paste" menu option appears (when there's text in the clipboard). This is what I'm trying to prevent.
From what I can see from the source, the ActionPopupWindow
is what pops up with the PASTE/REPLACE options. ActionPopupWindow is a protected variable (mActionPopupWindow) in the private abstract class HandleView within public class android.widget.Editor...
Short of disabling the clipboard service or editing the Android Source code, is there a way that I can prevent this from showing? I tried to define a new style for android:textSelectHandleWindowStyle
, and set android:visibility
to gone
, but it didn't work (app froze for a while when it would otherwise have shown).
Solution: Override isSuggestionsEnabled
and canPaste
in EditText
.
For the quick solution, copy the class below - this class overrides the EditText
class, and blocks all events accordingly.
For the gritty details, keep reading.
The solution lies in preventing PASTE/REPLACE menu from appearing in the show()
method of the (non-documented) android.widget.Editor
class. Before the menu appears, a check is done to if (!canPaste && !canSuggest) return;
. The two methods that are used as the basis to set these variables are both in the EditText
class:
isSuggestionsEnabled()
is public, and may thus be overridden.canPaste()
is not, and thus must be hidden by introducing a function of the same name in the derived class.
So incorporating these updates into a class that also has the setCustomSelectionActionModeCallback, and the disabled long-click, here is the full class to prevent all editing (but still display the text selection handler) for controlling the cursor:
package com.cjbs.widgets;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
/**
* This is a thin veneer over EditText, with copy/paste/spell-check removed.
*/
public class NoMenuEditText extends EditText
{
private final Context context;
/** This is a replacement method for the base TextView class' method of the same name. This
* method is used in hidden class android.widget.Editor to determine whether the PASTE/REPLACE popup
* appears when triggered from the text insertion handle. Returning false forces this window
* to never appear.
* @return false
*/
boolean canPaste()
{
return false;
}
/** This is a replacement method for the base TextView class' method of the same name. This method
* is used in hidden class android.widget.Editor to determine whether the PASTE/REPLACE popup
* appears when triggered from the text insertion handle. Returning false forces this window
* to never appear.
* @return false
*/
@Override
public boolean isSuggestionsEnabled()
{
return false;
}
public NoMenuEditText(Context context)
{
super(context);
this.context = context;
init();
}
public NoMenuEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
this.context = context;
init();
}
public NoMenuEditText(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
this.context = context;
init();
}
private void init()
{
this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
this.setLongClickable(false);
}
/**
* Prevents the action bar (top horizontal bar with cut, copy, paste, etc.) from appearing
* by intercepting the callback that would cause it to be created, and returning false.
*/
private class ActionModeCallbackInterceptor implements ActionMode.Callback
{
private final String TAG = NoMenuEditText.class.getSimpleName();
public boolean onCreateActionMode(ActionMode mode, Menu menu) { return false; }
public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; }
public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; }
public void onDestroyActionMode(ActionMode mode) {}
}
}
I've tested this in Android v4.4.2 and v4.4.3.
這篇關于EditText:禁用文本選擇處理程序單擊事件上的粘貼/替換菜單彈出的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!