从EditText禁用软键盘但仍允许复制/粘贴?

时间:2013-03-02 12:43:46

标签: android android-edittext

您好我正在制作自定义拨号器,因此我创建了自己的输入板。

问题是如何禁用EditText 但仍允许剪切/复制/粘贴?股票拨号器可以执行此操作。

我尝试了android:focusable="false"但是它禁用了剪切/复制(但仍然可以粘贴)。

我还尝试以编程方式禁用inputType,这会禁用所有三个命令:

myEditText.setInputType(InputType.TYPE_NULL); //Can't cut/copy/paste

从清单中禁用它也不起作用:

android:configChanges="orientation|keyboardHidden" //Keyboard still popped up

任何解决方案?感谢

7 个答案:

答案 0 :(得分:51)

经过数小时和数小时的研究,我终于找到了适用于所有API版本的解决方案。希望这能节省一些人的时间。

如果您正在为API> = 11开发,解决方案很简单:

1)在EditText的xml文件中添加以下两个属性

android:inputType="none"
android:textIsSelectable="true"

2)以编程方式执行以下操作

myEditText.setInputType(InputType.TYPE_NULL);
myEditText.setTextIsSelectable(true);

你已经完成了。

如果您想满足API< 11,我发现如果你想选择用于复制粘贴目的的文本,则无法禁用键盘弹出。将focusable设置为false将禁用键盘但它没有帮助,因为它也会禁用您选择文本的能力。我在stackoverflow中找到的任何其他解决方案都无法正常工作或同时禁用文本选择。

解决这个问题的一个丑陋方法是......

首先,在EditText的

android:editable="false"

是的,这已被弃用,但是必须使EditText在API版本中不可编辑< 11。

接下来,我们需要在键盘出现后立即隐藏它,这样我们就可以继续选择文字而不会阻挡键盘。

使用以下代码检测键盘显示(从https://stackoverflow.com/a/9108219/1241783获得的解决方案),并立即隐藏它。

if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
{
    final View activityRootView = findViewById(R.id.activityRoot);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
        public void onGlobalLayout() {
            Rect r = new Rect();
            //r will be populated with the coordinates of your view that area still visible.
            activityRootView.getWindowVisibleDisplayFrame(r);

            int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
            if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...

            //Hide the keyboard instantly!
            if (getCurrentFocus() != null) 
            {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
            }
            }
         }
        });
}

它适用于我的情况。虽然你可以看到键盘在一瞬间出现(这是丑陋的部分),但在写作的时候我想不出任何其他方式让它工作。如果您有更好的解决方案,请发表评论!

如果这可以节省某人的时间,也让我知道:)

答案 1 :(得分:33)

要禁用软键盘显示,保留复制/粘贴和光标功能,只需在活动中添加以下行:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

答案 2 :(得分:7)

由于当前的最佳答案使用了一种已弃用的方法,而且我没有使用粘贴方法,因此这是另一种不使用旧方法的方法。但是,它确实尝试通过反射使用隐藏方法。 =)

我已将EditText子类化为名为KeyboardlessEditText的新窗口小部件,该窗口小部件仍保留所有酷炫的编辑功能,而不显示键盘。只需将文件放入即可。

这篇文章的完整代码有点长,但只要GitHub没有关闭,那么这将有效:https://github.com/danialgoodwin/android-widget-keyboardless-edittext/blob/master/KeyboardlessEditText2.java

答案 3 :(得分:3)

要禁用系统键盘自动弹出EditTextTextView,请执行以下操作:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    editTextView.setShowSoftInputOnFocus(false);
} else {
    editTextView.setTextIsSelectable(true);
    //N.B. Accepting the case when non editable text will be selectable
}

答案 4 :(得分:2)

试试这个

 EditText et = ... // your EditText

et.setKeyListener(null) //makes the EditText non-editable so, it acts like a TextView.

无需子类。这与EditText不可聚焦之间的主要区别在于EditText仍然有自己的光标 - 你可以选择文本等等。它只是阻止IME弹出自己的软键盘。

答案 5 :(得分:1)

由于我自定义的内联“伪”输入而有类似的需求,当焦点移至编辑文本后os软键盘出现时,该输入仍然可见。 解决方案是使编辑文本隐藏软输入,直到以前的自定义输入窗口小部件完成其编辑生命周期为止。

@Bruce's answer为灵感,还看到了一些相关的帖子,我将在结尾处附加。 我发现有效的解决方案是:

fun setInputType(inputType: Int) {
        getEditText().setRawInputType(inputType)
        if (inputType == InputType.TYPE_NULL) {
            getEditText().setTextIsSelectable(true)
            getEditText().isCursorVisible = true
        }
    }

必须使用setRawInputType()来代替,因为从InputType.TYPE_NULL设置回InputType.TYPE_TEXT_FLAG_MULTI_LINE时,多行文本输入不受重视。

似乎有些用户报告与呼叫setInputType(InputType.TYPE_NULL)有关的问题。看到: https://issuetracker.google.com/issues/36907992

其他有用的相关帖子:

How to make EditText not editable through XML in Android?

EditText non editable

答案 6 :(得分:1)

我遇到了同样的问题,但我也希望以后在doulbe轻击后允许输入。.几个小时后,我找到了可行的解决方案(至少对我而言)。在您的onCreate方法中使用它:

editText.setCursorVisible(false);
editText.setTextIsSelectable(true);
editText.setShowSoftInputOnFocus(false);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);  // This just hide keyboard when activity starts

这些行绝对可以解决问题..如果您想还原该行,请使用以下命令:

editText.setCursorVisible(true);
editText.setShowSoftInputOnFocus(true);

要再次显示键盘,请使用:

private void showSoftKeyboard(View view) {
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
    view.requestFocus();
    inputMethodManager.showSoftInput(view, 0);
}

要允许下次复制/粘贴,请使用以下三行:

editText.setCursorVisible(false);
editText.setTextIsSelectable(true);
editText.setShowSoftInputOnFocus(false);

要进一步隐藏键盘,请使用:

private void hideSoftKeyboard() {
    if(getCurrentFocus() != null) {
        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    }
}

此代码适用于API> =21。希望对您有所帮助