The question:
I’m doing a calculator.
So I made my own Buttons
with numbers and functions.
The expression that has to be calculated, is in an EditText
, because I want users can add numbers or functions also in the middle of the expression, so with the EditText
I have the cursor
. But I want to disable the Keyboard
when users click on the EditText
.
I found this example that it’s ok for Android 2.3
, but with ICS
disable the Keyboard
and also the cursor.
public class NoImeEditText extends EditText {
public NoImeEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onCheckIsTextEditor() {
return false;
}
}
And then I use this NoImeEditText
in my XML
file
<com.my.package.NoImeEditText
android:id="@+id/etMy"
....
/>
How I can make compatible this EditText with ICS???
Thanks.
The Solutions:
Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.
Method 1
Below code is both for API >= 11 and API < 11. Cursor is still available.
/**
* 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);
}
}
Method 2
Here is a website that will give you what you need
As a summary, it provides links to InputMethodManager
and View
from Android Developers. It will reference to the getWindowToken
inside of View
and hideSoftInputFromWindow()
for InputMethodManager
A better answer is given in the link, hope this helps.
here is an example to consume the onTouch event:
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
}
};
Here is another example from the same website. This claims to work but seems like a bad idea since your EditBox is NULL it will be no longer an editor:
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
}
});
Hope this points you in the right direction
Method 3
You can also use setShowSoftInputOnFocus(boolean) directly on API 21+ or through reflection on 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
}
}
Method 4
Add below properties to the Edittext controller in the layout file
<Edittext
android:focusableInTouchMode="true"
android:cursorVisible="false"
android:focusable="false" />
I have been using this solution for while and it works fine for me.
Method 5
editText.setShowSoftInputOnFocus(false);
Method 6
try: android:editable="false"
or android:inputType="none"
Method 7
Disable the keyboard (API 11 to current)
This is the best answer I have found so far to disable the keyboard (and I have seen a lot of them).
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // API 21
editText.setShowSoftInputOnFocus(false);
} else { // API 11-20
editText.setTextIsSelectable(true);
}
There is no need to use reflection or set the InputType
to null.
Re-enable the keyboard
Here is how you re-enable the keyboard if needed.
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);
}
See this Q&A for why the complicated pre API 21 version is needed to undo setTextIsSelectable(true)
:
This answer needs to be more thoroughly tested.
I have tested the setShowSoftInputOnFocus
on higher API devices, but after @androiddeveloper’s comment below, I see that this needs to be more thoroughly tested.
Here is some cut-and-paste code to help test this answer. If you can confirm that it does or doesn’t work for API 11 to 20, please leave a comment. I don’t have any API 11-20 devices and my emulator is having problems.
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);
}
}
}
Method 8
Gathering solutions from multiple places here on StackOverflow, I think the next one sums it up:
If you don’t need the keyboard to be shown anywhere on your activity, you can simply use the next flags which are used for dialogs (got from here) :
getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
If you don’t want it only for a specific EditText, you can use this (got from 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;
}
Or this (taken from here) :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
editText.setShowSoftInputOnFocus(false);
else
editText.setTextIsSelectable(true);
Method 9
To add to Alex Kucherenko solution: the issue with the cursor getting disappearing after calling setInputType(0)
is due to a framework bug on ICS (and JB).
The bug is documented here: https://code.google.com/p/android/issues/detail?id=27609.
To workaround this, call setRawInputType(InputType.TYPE_CLASS_TEXT)
right after the setInputType
call.
To stop the keyboard from appearing, just override OnTouchListener
of the EditText and return true (swallowing the touch event):
ed.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
The reasons for the cursor appearing on GB devices and not on ICS+ had me tearing my hair out for a couple of hours, so I hope this saves someone’s time.
Method 10
I found this solution which works for me. It also places the cursor, when clicked on EditText at the correct position.
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;
}
});
Method 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);
Method 12
Just set:
NoImeEditText.setInputType(0);
or in the constructor:
public NoImeEditText(Context context, AttributeSet attrs) {
super(context, attrs);
setInputType(0);
}
Method 13
This worked for me.
First add this android:windowSoftInputMode="stateHidden"
in your android manifest file, under your activity. like below:
<activity ... android:windowSoftInputMode="stateHidden">
Then on onCreate method of youractivity, add the foloowing code:
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;
}
});
Then if you want the pointer to be visible add this on your xml android:textIsSelectable="true"
.
This will make the pointer visible.
In this way the keyboard will not popup when your activity starts and also will be hidden when you click on the edittext.
Method 14
Just put this line inside the activity tag in manifest
android:windowSoftInputMode=”stateHidden”
Method 15
In my case, these lines work for me…
android:inputType="none"
android:focusableInTouchMode="true"
android:cursorVisible="false"
android:focusable="false"
before adding these lines, When I clicked on editText default keyboard showed/invoked.
After adding these lines keyboard was not displayed.
Method 16
One way to disable keyboard on EditText is
binding.InputTextView.showSoftInputOnFocus = false
Method 17
I don´t know if this answer is the better, but i found a possible faster solution. On XML, just put on EditText this attributes:
android:focusable="true"
android:focusableInTouchMode="false"
And then do what you need with onClickListener.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0