34

Hi I'm making custom dialer so I create my own input pad.

The problem is how do I disable the EditText but still allow cut/copy/paste? The stock dialer can do this.

I have tried android:focusable="false" but it disables cut/copy (can still paste though).

I also tried to disable the inputType programatically which disables all three commands:

myEditText.setInputType(InputType.TYPE_NULL); //Can't cut/copy/paste

Disabling it from manifest also doesn't work:

android:configChanges="orientation|keyboardHidden" //Keyboard still popped up

Any solution? Thanks

hrsetyono
  • 4,474
  • 13
  • 46
  • 80

7 Answers7

58

After hours and hours of research, I finally found a solution that works for all API versions. Hope this saves someone's time.

If you are developing for API >= 11, the solution is simple, either:

1) Add the two properties below in the xml file of EditText

android:inputType="none"
android:textIsSelectable="true"

or

2) Programatically do the below

myEditText.setInputType(InputType.TYPE_NULL);
myEditText.setTextIsSelectable(true);

And you're done.

If you want to cater for API < 11 as well, I found that there is no way to disable to keyboard from popping out if you wanted to select the text for copy paste purpose. Setting focusable to false will disable the keyboard but it doesn't help because it disables your ability to select text too. Any other solutions I found in stackoverflow all either doesn't work or disables text selection at the same time too.

One ugly way to solve this is as such..

First, add this property in the xml file of EditText

android:editable="false"

Yes this is deprecated, but necessary for making the EditText not editable in API version < 11.

Next, we will need to hide the keyboard as soon as it shows up, so that we can continue selecting text without the keyboard blocking the way.

Use this code below to detect keyboard showing up (solution obtained from https://stackoverflow.com/a/9108219/1241783), and hide it immediately.

if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
{
    final View activityRootView = findViewById(R.id.activityRoot);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
        public void onGlobalLayout() {
            Rect r = new Rect();
            //r will be populated with the coordinates of your view that area still visible.
            activityRootView.getWindowVisibleDisplayFrame(r);

            int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
            if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...

            //Hide the keyboard instantly!
            if (getCurrentFocus() != null) 
            {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
            }
            }
         }
        });
}

It works for my case. Though you can see the keyboard showing up in a split second (which is the ugly part) but I can't think of any other way to get this to work at the time of writing. If you have a better solution, please leave a comment!

Let me know too if this saves someone's time :)

Community
  • 1
  • 1
Bruce
  • 2,357
  • 5
  • 29
  • 50
  • Thanks, this works better than what I was using before, but still no default paste option for at least KitKat? I just see select all and copy on long-press.. – Anonsage Jun 01 '14 at 01:04
  • 3
    It's nice but `myEditText.setInputType(InputType.TYPE_NULL);` makes EditText single line, even in combination `InputType.TYPE_NULL | InputType.TYPE_TEXT_FLAG_MULTI_LINE` – Quark Aug 02 '16 at 14:28
  • I only had to do `android:textIsSelectable="true"`. Is there any need for `myEditText.setInputType(InputType.TYPE_NULL);`? – Suragch Jul 21 '17 at 00:58
  • @Suragch if you need to disable the soft-keyboard (no typing allowed) then yes – Bruce Jul 27 '17 at 01:14
  • In my tests the soft keyboard was disabled without setting the `InputType`. What Android API version did it require it for you? – Suragch Jul 27 '17 at 03:38
  • Code (1) works lovely for me. Can also use `android:selectAllOnFocus="true"` with it. – ban-geoengineering May 12 '19 at 15:22
  • @Quark I just ran into the same issue regarding multi line not respected when i set it back after setting to null - for me this was solved by setting programmatically `setRawInputType(type)` instead of `inputType(inputType)` – lecker909 Nov 13 '19 at 16:55
37

To disable the soft keyboard showing, keeping the copy/paste and cursor functionality, just add this line in your activity:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
Santacrab
  • 3,165
  • 2
  • 25
  • 31
  • 1
    This worked for me just fine, leaves the cursor intact and the context menu, plus, it works on Android O (v.26). My requirements are v.19 thru v.26. I put it in the onCreate method of the activity that contains the EditText control. – Gail Sep 06 '17 at 20:57
7

Since the current top answer uses a deprecated method and didn't have the paste method for me, here's another way that doesn't use old methods. But, it does try to use a hidden method via reflection with a fallback. =)

I've subclassed EditText into a new widget called KeyboardlessEditText that still retains all the cool editing features without the keyboard showing. Just drop the file in and go.

The full code is a little long for this post, but as long as GitHub doesn't go down, then this will work: https://github.com/danialgoodwin/android-widget-keyboardless-edittext/blob/master/KeyboardlessEditText2.java

Anonsage
  • 8,030
  • 5
  • 48
  • 51
  • this is awesome and almost perfect! Almost becuase it still shows keyboard in one scenario: if you send app in background, and then return back, then it shows keyboard :( Any help for this? I've tried accepted answer (doesn't work), and also have tried set parent focusable but no help...still haven't found solution that gives me no keyboard but with copy/paste – daneejela Nov 20 '14 at 05:20
  • For which method(s) of sending app to background (and opening) does the keyboard show? I wasn't able to recreate this in the six different close/open combinations I tried (using Nexus 4 API 21). – Anonsage Nov 27 '14 at 03:36
7

To disable system keyboard automatic pop up for EditText or TextView do the following:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    editTextView.setShowSoftInputOnFocus(false);
} else {
    editTextView.setTextIsSelectable(true);
    //N.B. Accepting the case when non editable text will be selectable
}
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
Shahidul
  • 2,997
  • 1
  • 21
  • 20
4

I had the same problem but later I also wanted allow typing after double tap.. after hours and hours of searching I found working solution (at least for me). Use this in your onCreate method:

editText.setCursorVisible(false);
editText.setTextIsSelectable(true);
editText.setShowSoftInputOnFocus(false);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);  // This just hide keyboard when activity starts

These lines should definitely do the trick.. and if you want to revert that use this:

editText.setCursorVisible(true);
editText.setShowSoftInputOnFocus(true);

To show keyboard again use:

private void showSoftKeyboard(View view) {
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
    view.requestFocus();
    inputMethodManager.showSoftInput(view, 0);
}

To allow copy/paste next time just use these three lines:

editText.setCursorVisible(false);
editText.setTextIsSelectable(true);
editText.setShowSoftInputOnFocus(false);

For further keyboard hide use:

private void hideSoftKeyboard() {
    if(getCurrentFocus() != null) {
        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    }
}

This code is working on API >= 21

B8ightY
  • 469
  • 5
  • 5
  • This might help someone. I had created a keypad layout using Buttons and I'm loading it as a fragment. I therefore wanted to disable the soft keyboard without disabling the (blinking) cursor. Using `editText.setShowSoftInputOnFocus(false);` gets the job done. The user can still click to place the cursor where an edit needs to be made. Now I need to write code to backspace the cursor so the edit can be made. Android is such an adventure. I love it. –  Apr 25 '20 at 14:00
3

try this

 EditText et = ... // your EditText

et.setKeyListener(null) //makes the EditText non-editable so, it acts like a TextView.

No need to subclass. The main difference between this and making your EditText non-focusable, is that the EditText still has its own cursor - you can select text, etc. All it does is suppress the IME from popping up its own soft keyboard.

1

Had a similar need due to my custom inline "fake" input which was still visible as the os soft keypad was appearing after focus moved to an edit text. Solution was to make the edit text hide soft input until the previous custom input widget had finished its edit lifecycle.

Used @Bruce's answer for inspiration, also saw a few related posts which I'll attach at end. Solution I found worked was:

fun setInputType(inputType: Int) {
        getEditText().setRawInputType(inputType)
        if (inputType == InputType.TYPE_NULL) {
            getEditText().setTextIsSelectable(true)
            getEditText().isCursorVisible = true
        }
    }

had to use setRawInputType() instead as multiline text input was not respected when setting from InputType.TYPE_NULL back to InputType.TYPE_TEXT_FLAG_MULTI_LINE.

Seems there are users reporting issues relating to calling setInputType(InputType.TYPE_NULL). see: https://issuetracker.google.com/issues/36907992

other useful related posts:

How to make EditText not editable through XML in Android?

EditText non editable

lecker909
  • 181
  • 3
  • 6