在 EditText 上禁用键盘

Posted

技术标签:

【中文标题】在 EditText 上禁用键盘【英文标题】:Disable keyboard on EditText 【发布时间】:2012-05-25 02:00:46 【问题描述】:

我正在做一个计算器。 所以我用数字和函数制作了自己的Buttons。 必须计算的表达式在EditText 中,因为我希望用户也可以在表达式中间添加数字或函数,所以EditText 我有cursor。但是当用户单击EditText 时,我想禁用Keyboard。 我发现这个例子对于android 2.3 是可以的,但是使用ICS 禁用Keyboard 和光标。

public class NoImeEditText extends EditText 

   public NoImeEditText(Context context, AttributeSet attrs)  
      super(context, attrs);     
      

   @Override      
   public boolean onCheckIsTextEditor()    
       return false;     
            

然后我在我的XML 文件中使用这个NoImeEditText

<com.my.package.NoImeEditText
      android:id="@+id/etMy"
 ....  
/>

如何使这个 EditText 与 ICS 兼容??? 谢谢。

【问题讨论】:

您是如何制作每个按钮以将文本放置在 EditText 中的正确位置(在文本光标/插入符号上)? 【参考方案1】:

以下代码适用于 API >= 11 和 API

/**
 * Disable soft keyboard from appearing, use in conjunction with android:windowSoftInputMode="stateAlwaysHidden|adjustNothing"
 * @param editText
 */
public static void disableSoftInputFromAppearing(EditText editText) 
    if (Build.VERSION.SDK_INT >= 11) 
        editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
        editText.setTextIsSelectable(true);
     else 
        editText.setRawInputType(InputType.TYPE_NULL);
        editText.setFocusable(true);
    

【讨论】:

任何想法如何在使用此禁用方法后重新启用键盘? 是的。这是个好问题@kort.es .. 请回答 Aleksey,怎么样? 由于 API >= 11 很常见,同样可以通过xml参数实现:android:inputType="text" android:textIsSelectable="true" 我使用editText.setRawInputType(editText.getInputType()); 而不是简单的editText.setRawInputType(InputType.TYPE_CLASS_TEXT); - 这可以确保维护XML 中的任何inputType 设置。 setRawInputType(...)setInputType(0) 好,因为它没有禁用光标。【参考方案2】:

Here 是一个可以为您提供所需内容的网站

总而言之,它提供了来自 Android 开发者的 InputMethodManagerView 的链接。它将引用ViewhideSoftInputFromWindow() 内部的getWindowToken InputMethodManager

链接中给出了更好的答案,希望对您有所帮助。

这里是一个使用 onTouch 事件的例子:

editText_input_field.setOnTouchListener(otl);

private OnTouchListener otl = new OnTouchListener() 
  public boolean onTouch (View v, MotionEvent event) 
        return true; // the listener has consumed the event
  
;

这是来自同一网站的另一个示例。这声称有效,但似乎是个坏主意,因为您的 EditBox 为 NULL,它将不再是编辑器:

MyEditor.setOnTouchListener(new OnTouchListener()

  @Override
  public boolean onTouch(View v, MotionEvent event) 
    int inType = MyEditor.getInputType(); // backup the input type
    MyEditor.setInputType(InputType.TYPE_NULL); // disable soft input
    MyEditor.onTouchEvent(event); // call native handler
    MyEditor.setInputType(inType); // restore input type
    return true; // consume touch even
  
);

希望这会为您指明正确的方向

【讨论】:

第二个例子是解决方案 :D 谢谢!也适用于 ICS...其他示例仅适用于旧版本的 Android,如 2.3.... 不适用于 2.1 中的多行 EditText。经过这样的伎俩,观点扭曲了。滚动和光标也不起作用。 对于这么简单的事情似乎有点破解。 我不知道为什么,但是添加此代码后它不能与光标一起使用:-( etSearchEnglish.setInputType(InputType.TYPE_NULL); // 禁用显示键盘,对我有用!【参考方案3】:

您也可以直接在 API 21+ 上使用 setShowSoftInputOnFocus(boolean) 或通过 API 14+ 上的反射:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
    editText.setShowSoftInputOnFocus(false);
 else 
    try 
        final Method method = EditText.class.getMethod(
                "setShowSoftInputOnFocus"
                , new Class[]boolean.class);
        method.setAccessible(true);
        method.invoke(editText, false);
     catch (Exception e) 
        // ignore
    

【讨论】:

这个想法很好,但是它不适用于 API 14-15,但适用于 16+。对于 API 15,可以使用名为“setSoftInputShownOnFocus”的方法。 我对此赞不绝口!!!!感谢Android简单解决了很久的问题!【参考方案4】:

将以下属性添加到布局文件中的 Edittext 控制器

<Edittext
   android:focusableInTouchMode="true"
   android:cursorVisible="false"
   android:focusable="false"  />

我一直在使用这个解决方案,它对我来说很好。

【讨论】:

这是最快的方法:P【参考方案5】:
editText.setShowSoftInputOnFocus(false);

【讨论】:

这个答案比其他答案更好,因为我需要我的 EditText 对其他触摸事件有效,比如“setError”消息。禁用焦点也会禁用所有触摸事件。 最后唯一有效的答案。而且就这么简单…… 【参考方案6】:

试试:android:editable="false"android:inputType="none"

【讨论】:

【参考方案7】:

禁用键盘(API 11 到当前)

这是迄今为止我找到的禁用键盘的最佳答案(我见过很多)。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)  // API 21
    editText.setShowSoftInputOnFocus(false);
 else  // API 11-20
    editText.setTextIsSelectable(true);

无需使用反射或将InputType设置为null。

重新启用键盘

如果需要,您可以通过以下方式重新启用键盘。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)  // API 21
    editText.setShowSoftInputOnFocus(true);
 else  // API 11-20
    editText.setTextIsSelectable(false);
    editText.setFocusable(true);
    editText.setFocusableInTouchMode(true);
    editText.setClickable(true);
    editText.setLongClickable(true);
    editText.setMovementMethod(ArrowKeyMovementMethod.getInstance());
    editText.setText(editText.getText(), TextView.BufferType.SPANNABLE);

请参阅此问答,了解为什么需要复杂的 pre API 21 版本来撤消setTextIsSelectable(true)

How to enable keyboard on touch after disabling it with setTextIsSelectable

这个答案需要更彻底的测试。

我已经在更高的 API 设备上测试了setShowSoftInputOnFocus,但是在下面@androiddeveloper 的评论之后,我发现这需要进行更彻底的测试。

这里有一些剪切和粘贴代码来帮助测试这个答案。如果您可以确认它是否适用于 API 11 到 20,请发表评论。我没有任何 API 11-20 设备,而且我的模拟器有问题。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_
    android:layout_
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:background="@android:color/white">

    <EditText
        android:id="@+id/editText"
        android:textColor="@android:color/black"
        android:layout_
        android:layout_/>

    <Button
        android:text="enable keyboard"
        android:onClick="enableButtonClick"
        android:layout_
        android:layout_/>

    <Button
        android:text="disable keyboard"
        android:onClick="disableButtonClick"
        android:layout_
        android:layout_/>
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity 

    EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = (EditText) findViewById(R.id.editText);
    

    // when keyboard is hidden it should appear when editText is clicked
    public void enableButtonClick(View view) 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)  // API 21
            editText.setShowSoftInputOnFocus(true);
         else  // API 11-20
            editText.setTextIsSelectable(false);
            editText.setFocusable(true);
            editText.setFocusableInTouchMode(true);
            editText.setClickable(true);
            editText.setLongClickable(true);
            editText.setMovementMethod(ArrowKeyMovementMethod.getInstance());
            editText.setText(editText.getText(), TextView.BufferType.SPANNABLE);
        
    

    // when keyboard is hidden it shouldn't respond when editText is clicked
    public void disableButtonClick(View view) 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)  // API 21
            editText.setShowSoftInputOnFocus(false);
         else  // API 11-20
            editText.setTextIsSelectable(true);
        
    

【讨论】:

对于旧版本,使用 "setTextIsSelectable" 似乎是一个奇怪的选择。它的名字并不意味着它应该以这种方式工作。你在很多设备上测试过吗? @androiddeveloper,我没有在很多设备上测试它。我现在正在尝试在较低的 API 上对其进行测试,但我的模拟器遇到了问题。如果您或其他任何人可以确认它是否有效,请留下另一条评论。 它在我测试过的少数设备上运行良好,但我发现的反射方法也是如此(写在这里:***.com/a/45274277/878126)。一般来说,反射被认为是一种危险的东西,但反射函数的名称比“setTextIsSelectable”更好。 @androiddeveloper,具体来说您使用哪个 pre API 21 设备测试setTextIsSelectable 我觉得其中一个叫“Samsung Galaxy Young”。【参考方案8】:

在***这里从多个地方收集解决方案,我想下一个总结一下:

如果您不需要在活动的任何位置显示键盘,您可以简单地使用用于对话框的下一个标志(来自here):

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

如果您不希望它只用于特定的 EditText,您可以使用它(来自 here):

public static boolean disableKeyboardForEditText(@NonNull EditText editText) 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
        editText.setShowSoftInputOnFocus(false);
        return true;
    
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
        try 
            final Method method = EditText.class.getMethod("setShowSoftInputOnFocus", new Class[]boolean.class);
            method.setAccessible(true);
            method.invoke(editText, false);
            return true;
         catch (Exception ignored) 
        
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
        try 
            Method method = TextView.class.getMethod("setSoftInputShownOnFocus", boolean.class);
            method.setAccessible(true);
            method.invoke(editText, false);
            return true;
         catch (Exception ignored) 
        
    return false;

或者这个(取自here):

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
           editText.setShowSoftInputOnFocus(false);
       else
           editText.setTextIsSelectable(true); 

【讨论】:

我将尝试更多地测试标志解决方案。您已经在哪些 API 级别上对其进行了测试? “如果你不想要它只是为了......”:我想你的意思是说,“如果你只想要它......” 这是“不想要的”,因为它会阻止键盘显示。不想显示键盘 => 不会显示键盘。 关于 API 级别,我在 Android 6.0.x、4.2.x 和 5.x 上尝试过(具体不记得了)。 好的,我把“它”的意思是禁用,但现在我明白你的意思是键盘。【参考方案9】:

添加到 Alex Kucherenko 解决方案:调用 setInputType(0) 后光标消失的问题是由于 ICS(和 JB)上的框架错误。

错误记录在这里:https://code.google.com/p/android/issues/detail?id=27609。

要解决此问题,请在调用 setInputType 之后立即调用 setRawInputType(InputType.TYPE_CLASS_TEXT)

要阻止键盘出现,只需覆盖 EditText 的 OnTouchListener 并返回 true(吞下触摸事件):

ed.setOnTouchListener(new OnTouchListener() 

            @Override
            public boolean onTouch(View v, MotionEvent event) 

                return true;
            
        );

光标出现在 GB 设备上而不是 ICS+ 上的原因让我把头发扯了几个小时,所以我希望这可以节省一些人的时间。

【讨论】:

setInputType+setRawInputType 不起作用,因为它仍然会显示键盘。使用触摸事件聚焦时。以您所做的方式添加 setOnTouchListener 将解决此问题,但它不允许更改插入符号的位置或文本选择。【参考方案10】:

我找到了适合我的解决方案。当单击 EditText 时,它还会将光标放置在正确的位置。

EditText editText = (EditText)findViewById(R.id.edit_mine);
// set OnTouchListener to consume the touch event
editText.setOnTouchListener(new OnTouchListener() 

        @Override
        public boolean onTouch(View v, MotionEvent event) 
            v.onTouchEvent(event);   // handle the event first
            InputMethodManager imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm != null) 
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);  // hide the soft keyboard 
                            
            return true;
        
    );

【讨论】:

这个实现减慢了我的 Nexus 10 上触摸后的光标反应(大约 1 秒延迟)【参考方案11】:
// only if you completely want to disable keyboard for 
// that particular edit text
your_edit_text = (EditText) findViewById(R.id.editText_1);
your_edit_text.setInputType(InputType.TYPE_NULL);

【讨论】:

由于框架错误,这会导致光标在 ICS+ 设备上消失。请参阅下面的答案以获取可能的解决方案。【参考方案12】:

刚刚设置:

 NoImeEditText.setInputType(0);

或在构造函数中:

   public NoImeEditText(Context context, AttributeSet attrs)  
          super(context, attrs);   
          setInputType(0);
        

【讨论】:

在 Android 2.1-2.3 上这没问题,但在 ICS 中它也会禁用光标 =( 我不知道为什么... =( 我已经检查了我的一个应用程序,你是对的。感谢您的评论【参考方案13】:

这对我有用。 首先将此android:windowSoftInputMode="stateHidden" 添加到您的 android 清单文件中,在您的活动下。如下:

<activity ... android:windowSoftInputMode="stateHidden">

然后在你的activity的onCreate方法中,添加如下代码:

EditText editText = (EditText)findViewById(R.id.edit_text);
edit_text.setOnTouchListener(new OnTouchListener() 

    @Override
    public boolean onTouch(View v, MotionEvent event) 
        v.onTouchEvent(event);
        InputMethodManager inputMethod = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputMethod!= null) 
            inputMethod.hideSoftInputFromWindow(v.getWindowToken(), 0);
                        
        return true;
    
);

然后,如果您希望指针可见,请将其添加到您的 xml android:textIsSelectable="true"

这将使指针可见。 这样,当您的活动开始时键盘不会弹出,并且当您单击编辑文本时也会隐藏。

【讨论】:

【参考方案14】:

只需将此行放在清单中的活动标记内 android:windowSoftInputMode="stateHidden"

【讨论】:

【参考方案15】:

我不知道这个答案是否更好,但我找到了一个可能更快的解决方案。在 XML 上,只需在 EditText 上加上这个属性:

android:focusable="true"
android:focusableInTouchMode="false"

然后用 onClickListener 做你需要做的事情。

【讨论】:

以上是关于在 EditText 上禁用键盘的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中禁用 EditText

在 EditText 中阻止物理键盘输入

为啥我可以输入禁用的 EditText?

如何在editText聚焦时隐藏键盘

如何为特定活动禁用 Android 软键盘?

有没有办法禁用设置为数字的editText的“下一步”按钮?