Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android key event for back key when soft keyboard is shown?

I am trying to capture the "back" key event when the soft keyboard is shown.

I am using SDK ver 8 and can successfully capture the back key event ONLY when the soft keyboard is HIDDEN as follows:

@Override
public void onBackPressed() {
    // do something
    super.onBackPressed();
}

The problem is that the system is not calling this method while the soft keyboard is shown. I have tried to log onKeyDown/Up() methods as well as the above method to work out what is happening in this scenario to no avail. See below:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    //DEBUGGING
    Log.d(TAG + "KeyUP", String.valueOf(event));
}

Logs are returned for volume and menu keys as expected but the back key is only logged when the soft keyboard and menu are hidden.

Are there any "back key" guru's out there that can explain this phenomenon?

Any help is greatly appreciated.

like image 594
dan Avatar asked Oct 28 '13 14:10

dan


People also ask

How do I know if my Android keyboard is open soft?

Android provides no direct way to determine if the keyboard is open, so we have to get a little creative. The View class has a handy method called getWindowVisibleDisplayFrame from which we can retrieve a rectangle which contains the portion of the view visible to the user.

What is soft keyboard in Android?

The Android system shows an on-screen keyboard—known as a soft input method—when a text field in your UI receives focus.


2 Answers

Here is the way to capture back press key event: 1. Extend editText view to override onKeyPreIme

package com.test.test;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.EditText;

/**
 * Created by sumit.saurabh on 11/10/16.
 */
public class ChatEditText extends EditText
{
    /* Must use this constructor in order for the layout files to instantiate the class properly */
    public ChatEditText(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    private KeyImeChange keyImeChangeListener;

    public void setKeyImeChangeListener(KeyImeChange listener)
    {
        keyImeChangeListener = listener;
    }

    public interface KeyImeChange
    {
        public void onKeyIme(int keyCode, KeyEvent event);
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event)
    {
        if (keyImeChangeListener != null)
        {
            keyImeChangeListener.onKeyIme(keyCode, event);
        }
        return false;
    }
}
  1. ChatEditText in xml

        <com.test.test.ChatEditText
            android:id = "@+id/messageEditText"
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content"
            android:layout_gravity = "bottom"
            android:layout_marginLeft = "12dp"
            android:layout_marginRight = "30dp"
            android:background = "@null"
            android:hint = "Type your message"
            android:inputType = "textMultiLine"
            android:singleLine = "false"
            android:textColorHint = "#c4c0bd"
            android:textSize = "18sp"/>
    
  2. Then attach a listener (setKeyImeChangeListener) to the edit text:

    private ChatEditText messageEditText;
    messageEditText =
       (ChatEditText) findViewById(R.id.messageEditText);
    
    messageEditText.setKeyImeChangeListener(new ChatEditText.KeyImeChange(){
        @Override
        public void onKeyIme(int keyCode, KeyEvent event)
        {
            if (KeyEvent.KEYCODE_BACK == event.getKeyCode())
            {
                // do something
            }
        }});
    
like image 164
Sumit Saurabh Avatar answered Jan 17 '23 08:01

Sumit Saurabh


After digging around further on this site and the Android API I have found that

KeyEvent.KEYCODE_BACK

is caught and gobbled up by an IME that has an input method connection and that input method is currently shown (in other words; the soft keyboard is NOT hidden). This means that the event is consumed before the system calls the Activity classes onKeyDown() or onKeyUp() methods.

To get around this, create a sub-class of your IME widget (TextView or its child classes such as EditText) and implement onKeyPreIme().

Stack user i2097i has posted a good solution to implementing onKeyPreIme() in an activity here. Just make sure to return FALSE in your onKeyPreIme() Override if you wish to retain Androids default behaviour (i.e. closing the keyboard).

like image 39
dan Avatar answered Jan 17 '23 08:01

dan