Android EditText 屏蔽双击选中、长按选中

一、代码实现

同时屏蔽双击选中 和 长按选中:

mEditText.setMovementMethod(new BaseMovementMethod());

只屏蔽长按选中:

<EditText
        android:longClickable="false"
        />

二、分析、实现过程

双击或长按都是 Touch事件,所以先看EditText的onTouchEvent方法,EditText中 没有 onTouchEvent方法,而 class EditText extends TextView,所以查看TextView 的 onTouchEvent 方法。

// TextView.java
public boolean onTouchEvent(MotionEvent event) {
        final int action = event.getActionMasked();
        if (mEditor != null) {
            mEditor.onTouchEvent(event);
            ......
            }
// Editor.java
void onTouchEvent(MotionEvent event) {
        final boolean filterOutEvent = shouldFilterOutTouchEvent(event);
        mLastButtonState = event.getButtonState();
        if (filterOutEvent) {
            if (event.getActionMasked() == MotionEvent.ACTION_UP) {
                mDiscardNextActionUp = true;
            }
            return;
        }
        updateTapState(event);
        updateFloatingToolbarVisibility(event);

        // 重点:如果有SelectionController就使用它来处理 event
        if (hasSelectionController()) {
            getSelectionController().onTouchEvent(event); 
        }
class SelectionModifierCursorController implements CursorController {
    public void onTouchEvent(MotionEvent event) {
	    switch (event.getActionMasked()) {
	    	case MotionEvent.ACTION_UP:
                updateSelection(event);

updateSelection() --> updateSelectionInternal() --> Selection.setSelection((Spannable) mTextView.getText(), selectionStart, selectionEnd);
回到 Editor.java 中,

if (hasSelectionController()) {
    getSelectionController().onTouchEvent(event); 
}

getSelectionController().onTouchEvent(event); 中处理了选中的相关逻辑,也就是不走这行代码,就不会执行选中操作,只要想办法让 hasSelectionController()返回 false 即可。

// Editor.java
boolean hasSelectionController() {
    return mSelectionControllerEnabled;
}

void prepareCursorControllers() {
        mSelectionControllerEnabled = enabled && mTextView.textCanBeSelected();

enable肯定为true,那只有将mTextView.textCanBeSelected() == false

// TextView.java
boolean textCanBeSelected() {
    if (mMovement == null || !mMovement.canSelectArbitrarily()) return false;
    return isTextEditable()
            || (isTextSelectable() && mText instanceof Spannable && isEnabled());
}

return 语句中,isTextEditable() 肯定为true,如果走到了return这句就肯定不行了。
所以只有让程序走到这里去if (mMovement == null || !mMovement.canSelectArbitrarily()) return false;就ok了
看一下 MovementMethod 接口:

public interface MovementMethod {
    /**
     * Returns true if this movement method allows arbitrary selection
     * of any text; false if it has no selection (like a movement method
     * that only scrolls) or a constrained selection (for example
     * limited to links.  The "Select All" menu item is disabled
     * if arbitrary selection is not allowed.
     */
    public boolean canSelectArbitrarily();
}

意思就是,是否允许任意选择文本。

// EditText.java
    @Override
    protected MovementMethod getDefaultMovementMethod() {
        return ArrowKeyMovementMethod.getInstance();
    }

EditText的默认实现是 ArrowKeyMovementMethod 这玩意:

public class ArrowKeyMovementMethod extends BaseMovementMethod implements MovementMethod {
	@Override
    public boolean canSelectArbitrarily() {
        return true;
    }

那只要让canSelectArbitrarily()返回false即可,查看MovementMethod 的实现类后,我们可以使用

public class BaseMovementMethod implements MovementMethod {
    @Override
    public boolean canSelectArbitrarily() {
        return false;
    }

进行替代。
最终,使用 mEditText.setMovementMethod(new BaseMovementMethod()); 解决问题。
实际验证,效果也是OK的,既不能长按也不能双击选择文本。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洛克Lee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值