72

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.

Darshan Rivka Whittle
  • 29,749
  • 6
  • 81
  • 103
Ferox
  • 867
  • 1
  • 7
  • 9

15 Answers15

61

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);
    }
}
Andrew T.
  • 4,592
  • 7
  • 38
  • 55
Oleksii Malovanyi
  • 6,600
  • 6
  • 22
  • 26
  • 5
    any ideas how to enable keyboard back after using this disable method ? – kort.es Sep 26 '14 at 11:07
  • yeah. It is good question @kort.es .. Please answer Aleksey, how? – Mr. Robot Dec 20 '14 at 23:00
  • 1
    Since API >= 11 is very common, the same could be achieved by using xml parameters: `android:inputType="text" android:textIsSelectable="true"` – Murmel Jan 14 '16 at 11:09
  • Instead of simply `editText.setRawInputType(InputType.TYPE_CLASS_TEXT);` I use `editText.setRawInputType(editText.getInputType());` - this ensures that any inputType settings in the XML are maintained. – Clyde Jun 08 '16 at 01:06
  • 1
    `setRawInputType(...)` is better than `setInputType(0)` because it didn't disable the cursor. – vovahost Jul 31 '16 at 14:15
  • This code doesn't work on Samsung Galaxy S5 (klte, Android 6.0). Today I've received a review from a user. Is there any solution? – ViH Oct 14 '16 at 11:50
  • great job sir . I found this solution after many search and it really works better than `setInputType(InputType.TYPE_NULL)`. still cursor visible . thanks. – Dharmishtha May 03 '17 at 11:47
  • The problem with this is that it causes multi-line things to be single line. – fobbymaster May 10 '17 at 18:38
56

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

ken
  • 1,406
  • 2
  • 25
  • 63
Hip Hip Array
  • 4,425
  • 9
  • 45
  • 70
33

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
    }
}
kuelye
  • 606
  • 7
  • 9
  • 2
    The idea is good, however it doesn't work with API 14-15, but works with 16+. For API 15 it's possible to use method named "setSoftInputShownOnFocus". – Torsten Ojaperv Mar 31 '15 at 13:23
  • I can't upvote this enough!!!! Thank you Android for a simple solution for a long time problem! – Izak Sep 14 '20 at 00:09
21

try: android:editable="false" or android:inputType="none"

K_Anas
  • 30,228
  • 9
  • 65
  • 80
19

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.

Nishara MJ
  • 329
  • 2
  • 11
15

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);
        }
    }
}
Community
  • 1
  • 1
Suragch
  • 364,799
  • 232
  • 1,155
  • 1,198
  • For the older versions, this seems like a weird choice to use "setTextIsSelectable" . Its name doesn't imply it should work this way. Did you test it on a lot of devices? – android developer Jul 24 '17 at 08:17
  • @androiddeveloper, I didn't test it on a lot of devices. I'm trying to test it on the lower API's now but I'm having trouble with my emulator. If you or anyone else can confirm that it does or doesn't work, please leave another comment. – Suragch Jul 24 '17 at 09:33
  • Well it worked fine on the few devices I've tested, but so did the reflection methods I've found (written about it here: https://stackoverflow.com/a/45274277/878126 ) . Reflection in general is considered a dangerous thing to use, but the reflected functions have better name than "setTextIsSelectable". – android developer Jul 24 '17 at 10:03
  • @androiddeveloper, specifically which pre API 21 device did you use to test `setTextIsSelectable`? – Suragch Jul 24 '17 at 10:19
  • I think one of them is called "Samsung Galaxy Young". – android developer Jul 24 '17 at 12:04
  • @androiddeveloper, Oh, sorry, I mean which API level? – Suragch Jul 24 '17 at 22:13
  • I think it had Jelly Bean. – android developer Jul 25 '17 at 05:18
15
editText.setShowSoftInputOnFocus(false);
Kanagalingam
  • 1,607
  • 2
  • 17
  • 36
  • This answer is better than others for my needs, because i need my EditText to be active to other touch events, like the "setError" message. Disabling focus will disable all touch events too. – M. Marmor Apr 20 '21 at 09:28
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); 
android developer
  • 106,412
  • 122
  • 641
  • 1,128
6

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;
        }
    });
Vijay
  • 439
  • 3
  • 14
  • This implementation slows down the cursor reaction after touch very much (about 1 second delay) on my Nexus 10 – ViH Oct 21 '16 at 09:45
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);
Abel Terefe
  • 1,320
  • 19
  • 15
  • 1
    This causes the cursor to disappear on ICS+ devices due to framework bug. See my answer below for a possible solution. – Jay Sidri Jun 08 '13 at 14:03
5

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.

Jay Sidri
  • 5,877
  • 3
  • 36
  • 53
  • setInputType+setRawInputType don't work, as it will still show the keyboard. when focusing using touch events. Adding setOnTouchListener the way you did will solve this, but then it doesn't allow to change the location of the caret or selection of text. – android developer Jul 20 '17 at 14:27
4

Just set:

 NoImeEditText.setInputType(0);

or in the constructor:

   public NoImeEditText(Context context, AttributeSet attrs) { 
          super(context, attrs);   
          setInputType(0);
       } 
Alex Kucherenko
  • 19,361
  • 2
  • 24
  • 31
2

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.

Jerin A Mathews
  • 8,097
  • 3
  • 22
  • 41
2

Just put this line inside the activity tag in manifest android:windowSoftInputMode="stateHidden"

mahmoud alaa
  • 81
  • 1
  • 7
-1

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.

iLuuPii
  • 69
  • 6