【问题标题】:Disable soft-keyboard from EditText but still allow copy/paste?从 EditText 禁用软键盘但仍允许复制/粘贴?
【发布时间】:2013-02-16 22:48:18
【问题描述】:

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

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

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

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

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

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

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

有什么解决办法吗?谢谢

【问题讨论】:

    标签: android android-edittext


    【解决方案1】:

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

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

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

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

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

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

    你已经完成了。

    如果您也想满足 API

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

    首先,在EditText的xml文件中添加这个属性

    android:editable="false"
    

    是的,这已被弃用,但在 API 版本

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

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

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

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

    【讨论】:

    • 谢谢,这比我以前使用的效果更好,但至少 KitKat 仍然没有默认粘贴选项?我只看到全选并长按复制..
    • 这很好,但myEditText.setInputType(InputType.TYPE_NULL); 使 EditText 成为单行,即使组合 InputType.TYPE_NULL | InputType.TYPE_TEXT_FLAG_MULTI_LINE
    • 我只需要做android:textIsSelectable="true"。有没有myEditText.setInputType(InputType.TYPE_NULL);的需求?
    • @Suragch 如果您需要禁用软键盘(不允许输入),那么可以
    • 在我的测试中,软键盘在没有设置InputType的情况下被禁用。您需要哪个 Android API 版本?
    【解决方案2】:

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

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

    【讨论】:

    • 这对我来说很好用,保持光标和上下文菜单不变,此外,它适用于 Android O (v.26)。我的要求是 v.19 到 v.26。我把它放在包含 EditText 控件的活动的 onCreate 方法中。
    【解决方案3】:

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

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

    这篇文章的完整代码有点长,但只要 GitHub 不宕机,就可以了:https://github.com/danialgoodwin/android-widget-keyboardless-edittext/blob/master/KeyboardlessEditText2.java

    【讨论】:

    • 这太棒了,几乎完美!几乎是因为它在一种情况下仍然显示键盘:如果您在后台发送应用程序,然后返回,那么它会显示键盘:(对此有任何帮助吗?我尝试过接受的答案(不起作用),并且也尝试过设置父焦点但没有帮助...仍然没有找到没有键盘但复制/粘贴的解决方案
    • 键盘会显示哪些将应用程序发送到后台(和打开)的方法?我无法在我尝试的六种不同的关闭/打开组合中重新创建它(使用 Nexus 4 API 21)。
    【解决方案4】:

    要禁用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
    }
    

    【讨论】:

      【解决方案5】:

      试试这个

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

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

      【讨论】:

      • 感谢您的回复。但这种方式会隐藏光标,因此不允许我剪切/复制/粘贴。
      【解决方案6】:

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

      【讨论】:

      • 这可能对某人有所帮助。我使用按钮创建了一个键盘布局,并将其作为片段加载。因此,我想在不禁用(闪烁)光标的情况下禁用软键盘。使用editText.setShowSoftInputOnFocus(false); 可以完成工作。用户仍然可以单击以将光标放置在需要进行编辑的位置。现在我需要编写代码来退格光标以便进行编辑。 Android就是这样的冒险。我喜欢它。
      【解决方案7】:

      由于我的自定义内联“假”输入仍然可见,因为焦点移动到编辑文本后出现 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-15
        • 2018-02-24
        • 2018-01-19
        • 1970-01-01
        • 1970-01-01
        • 2011-09-10
        • 2017-08-15
        • 2014-01-18
        相关资源
        最近更新 更多