禁用EditText上的键盘


69

我在做计算器。所以我Buttons用数字和函数制作了自己的数字。有要计算的表达,是在EditText,因为我希望用户也可以在表达式中添加数字或功能,所以与EditText我有cursor。但是我想禁用Keyboard用户单击时的EditText。我发现此示例适合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;     
   }         
}

然后我NoImeEditTextXML文件中使用它

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

如何使此EditText与ICS兼容???谢谢。


如何使每个按钮将文本放在EditText中正确的位置(在文本光标/插入符号上)?
Android开发人员

Answers:


55

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

作为摘要,它提供了InputMethodManagerViewAndroid开发人员之间的链接。这将参照getWindowToken的内部ViewhideSoftInputFromWindow()用于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
  }
});

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


1
第二个例子是解决方案:D谢谢!还可与ICS一起使用...其他示例仅适用于旧版本的Android,如2.3 ....
Ferox 2012年

对于2.1中的多行EditText,效果不佳。这种技巧使视图失真。滚动和光标都不起作用。
halxinate

对于这么简单的东西似乎有点hack。
安德鲁·S

我不知道为什么,但是添加此代码后它不能与光标一起使用:-(
Slava

etSearchEnglish.setInputType(InputType.TYPE_NULL); //禁用显示键盘,对我有用!
Noor Hossain

61

下面的代码同时适用于API> = 11和API <11。游标仍然可用。

/**
 * 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);
    }
}

5
任何想法如何使用此禁用方法后启用键盘返回?
kort.es14

是的 @ kort.es是个好问题..请回答Aleksey,如何?
机器人先生2014年

1
由于API> = 11非常普遍,因此可以使用xml参数来实现相同的功能: android:inputType="text" android:textIsSelectable="true"
Murmel 2016年

而不是简单地editText.setRawInputType(InputType.TYPE_CLASS_TEXT);使用editText.setRawInputType(editText.getInputType());-这可以确保保留XML中的所有inputType设置。
克莱德(Clyde)

1
setRawInputType(...)优于setInputType(0)因为它没有禁用光标。
vovahost

28

您还可以直接在API 21+上或通过在API 14+上进行反射来使用setShowSoftInputOnFocus(boolean)

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
    }
}

2
这个主意很好,但是不适用于API 14-15,但适用于16+。对于API 15,可以使用名为“ setSoftInputShownOnFocus”的方法。
Torsten Ojaperv

我不能对此表示足够的支持!!!!感谢您为Android长期存在的问题提供简单的解决方案!
伊萨克

22

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


18

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

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

我使用此解决方案已有一段时间了,对我来说效果很好。


这是最快的方法:P
Akshay Shikre

14

禁用键盘(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);
}

有关为何需要撤消复杂的API 21之前版本的原因,请参见以下问答setTextIsSelectable(true)

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

我已经测试了 setShowSoftInputOnFocus在更高API的设备上,但是在下面@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_width="match_parent"
    android:layout_height="match_parent"
    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_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:text="enable keyboard"
        android:onClick="enableButtonClick"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <Button
        android:text="disable keyboard"
        android:onClick="disableButtonClick"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</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”似乎是一个奇怪的选择。它的名称并不意味着它应该以这种方式工作。您是否在很多设备上进行过测试?
Android开发人员

@androiddeveloper,我没有在很多设备上进行测试。我现在正在尝试在较低的API上对其进行测试,但是我的模拟器遇到了麻烦。如果您或任何其他人可以确认它是否有效,请再发表评论。
Suragch

很好,它在我测试过的少数设备上都可以正常工作,但是我发现的反射方法也可以(在这里写有关它:stackoverflow.com/a/45274277/878126)。通常,反射被认为是危险的事情,但是反射函数的名称比“ setTextIsSelectable”更好。
Android开发人员

@androiddeveloper,特别是您用来测试哪个API 21之前的设备setTextIsSelectable
Suragch

我认为其中之一被称为“三星银河青年”。
Android开发人员


8

我从StackOverflow的多个地方收集解决方案,我认为下一个总结起来:

如果您不需要在活动的任何地方显示键盘,则可以简单地使用下一个用于对话框的标志(从此处获取):

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

如果您不只希望将其用于特定的EditText,则可以使用它(从此处获取):

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;
}

或者这个(从这里获取):

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

我将尝试更多地测试标志解决方案。您已经在哪些API级别上对其进行了测试?
Suragch '17

“如果您不只是想要...”:我想您是想说,“如果您只是想要...”
Suragch

这是“不需要”,因为它阻止了键盘的显示。不想显示键盘=>不会显示键盘。
Android开发人员

关于API级别,我已经在Android 6.0.x,4.2.x和5.x上尝试过(不记得确切的级别)。
Android开发人员

好的,我用“它”来表示禁用,但是现在我知道您将它作为键盘了。
Suragch '17

6

我找到了适合我的解决方案。当单击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
ViH 2016年

5
// 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);

1
由于框架错误,这将导致光标在ICS +设备上消失。请参阅以下我的答案以寻求可能的解决方案。
杰伊·西德里


4

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

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

要解决此问题,请setRawInputType(InputType.TYPE_CLASS_TEXT)setInputType通话致电。

要停止显示键盘,只需覆盖OnTouchListenerEditText并返回true(吞下touch事件):

ed.setOnTouchListener(new OnTouchListener() {

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

                return true;
            }
        });

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


setInputType + setRawInputType不起作用,因为它仍会显示键盘。使用触摸事件进行聚焦时。以您的方式添加setOnTouchListener可以解决此问题,但随后不允许更改插入符号的位置或文本的选择。
Android开发人员

2

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

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

然后在youractivity的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"

这将使指针可见。这样,在您的活动开始时,键盘将不会弹出,而在您单击edittext时,键盘也将被隐藏。


2

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


-1

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

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

然后使用onClickListener完成您需要的操作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.