在 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 开发者的 InputMethodManager
和 View
的链接。它将引用View
和hideSoftInputFromWindow()
内部的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)
:
这个答案需要更彻底的测试。
我已经在更高的 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 上禁用键盘的主要内容,如果未能解决你的问题,请参考以下文章