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.
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.
The Android system shows an on-screen keyboard—known as a soft input method—when a text field in your UI receives focus.
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;
}
}
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"/>
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
}
}});
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With