33

嗨,我正在制作自定义拨号器,所以我创建了自己的输入板。

问题是如何禁用 EditText但仍允许剪切/复制/粘贴?股票拨号器可以做到这一点。

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

我还尝试以inputType编程方式禁用禁用所有三个命令的程序:

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

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

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

有什么解决办法吗?谢谢

4

7 回答 7

57

经过数小时的研究,我终于找到了适用于所有 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的xml文件中添加这个属性

android:editable="false"

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

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

使用下面的代码来检测键盘出现(从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);
            }
            }
         }
        });
}

它适用于我的情况。尽管您可以在一瞬间看到键盘出现(这是丑陋的部分),但在撰写本文时我想不出任何其他方法可以使其正常工作。如果您有更好的解决方案,请发表评论!

如果这可以节省某人的时间,请告诉我:)

于 2013-11-24T09:28:12.073 回答
34

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

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
于 2014-07-18T12:38:04.227 回答
7

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

我已经细分EditText为一个名为的新小部件KeyboardlessEditText,它仍然保留了所有很酷的编辑功能,而没有显示键盘。只需将文件放入并继续。

这篇文章的完整代码有点长,但只要 GitHub 不宕机,那么这将起作用:https ://github.com/danialgoodwin/android-widget-keyboardless-edittext/blob/master/KeyboardlessEditText2 .java

于 2014-06-05T01:21:32.047 回答
6

要禁用系统键盘自动弹出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
}
于 2017-02-16T06:07:33.150 回答
3

尝试这个

 EditText et = ... // your EditText

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

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

于 2013-03-02T15:03:14.053 回答
3

我遇到了同样的问题,但后来我也想在双击后允许打字。经过数小时的搜索后,我找到了可行的解决方案(至少对我而言)。在你的 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

于 2020-03-25T21:53:24.197 回答
1

由于我的自定义内联“假”输入仍然可见,因为在焦点移动到编辑文本后出现了 os 软键盘,因此有类似的需求。解决方案是让编辑文本隐藏软输入,直到之前的自定义输入小部件完成其编辑生命周期。

使用@Bruce 的答案来获得灵感,还看到了一些相关的帖子,我将在最后附上。我发现有效的解决方案是:

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

必须setRawInputType()改用,因为从InputType.TYPE_NULLback 设置为InputType.TYPE_TEXT_FLAG_MULTI_LINE.

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

其他有用的相关帖子:

如何在 Android 中通过 XML 使 EditText 不可编辑?

EditText 不可编辑

于 2019-11-13T17:18:28.743 回答