I know a way to do this. Subclass the EditText and implement:
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
// Do your thing.
return true; // So it is not propagated.
}
return super.dispatchKeyEvent(event);
}
Here is a link on how to use your custom views (for when you subclass EditText): http://developer.android.com/guide/topics/ui/custom-components.html
Jay, your solution is good ! thanks :)
public class EditTextBackEvent extends EditText {
private EditTextImeBackListener mOnImeBack;
public EditTextBackEvent(Context context) {
super(context);
}
public EditTextBackEvent(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextBackEvent(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK &&
event.getAction() == KeyEvent.ACTION_UP) {
if (mOnImeBack != null)
mOnImeBack.onImeBack(this, this.getText().toString());
}
return super.dispatchKeyEvent(event);
}
public void setOnEditTextImeBackListener(EditTextImeBackListener listener) {
mOnImeBack = listener;
}
}
public interface EditTextImeBackListener {
public abstract void onImeBack(EditTextBackEvent ctrl, String text);
}
I made a slight change on Jay's solution by calling super.onKeyPreIme():
_e = new EditText(inflater.getContext()) {
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK){
cancelTextInput();
}
return super.onKeyPreIme(keyCode, event);
}
};
Wonderful solution, Jay, +1!
Here is my custom EditText to detect whether keyboard is showing or not
/**
* Created by TheFinestArtist on 9/24/15.
*/
public class KeyboardEditText extends EditText {
public KeyboardEditText(Context context) {
super(context);
}
public KeyboardEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public KeyboardEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (listener != null)
listener.onStateChanged(this, true);
}
@Override
public boolean onKeyPreIme(int keyCode, @NonNull KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
&& event.getAction() == KeyEvent.ACTION_UP) {
if (listener != null)
listener.onStateChanged(this, false);
}
return super.onKeyPreIme(keyCode, event);
}
/**
* Keyboard Listener
*/
KeyboardListener listener;
public void setOnKeyboardListener(KeyboardListener listener) {
this.listener = listener;
}
public interface KeyboardListener {
void onStateChanged(KeyboardEditText keyboardEditText, boolean showing);
}
}
It's 2019 now...
So I created a more neat solution with Kotlin
1.Create an extension function:
fun Activity.addKeyboardToggleListener(onKeyboardToggleAction: (shown: Boolean) -> Unit): KeyboardToggleListener? {
val root = findViewById<View>(android.R.id.content)
val listener = KeyboardToggleListener(root, onKeyboardToggleAction)
return root?.viewTreeObserver?.run {
addOnGlobalLayoutListener(listener)
listener
}
}
2.Where the toggle listener is:
open class KeyboardToggleListener(
private val root: View?,
private val onKeyboardToggleAction: (shown: Boolean) -> Unit
) : ViewTreeObserver.OnGlobalLayoutListener {
private var shown = false
override fun onGlobalLayout() {
root?.run {
val heightDiff = rootView.height - height
val keyboardShown = heightDiff > dpToPx(200f)
if (shown != keyboardShown) {
onKeyboardToggleAction.invoke(keyboardShown)
shown = keyboardShown
}
}
}
}
fun View.dpToPx(dp: Float) = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resources.displayMetrics).roundToInt()
3.Use it in any Activity as simple as this:
addKeyboardToggleListener {shown ->
// hurray! Now you know when the keyboard is shown and hidden!!
}
Using @olivier_sdg's answer, but converted to Kotlin:
class KeyboardEditText : AppCompatEditText {
var listener: Listener? = null
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun onKeyPreIme(keyCode: Int, event: KeyEvent): Boolean {
if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
listener?.onImeBack(this)
}
return super.dispatchKeyEvent(event)
}
interface Listener {
fun onImeBack(editText: KeyboardEditText)
}
}
Usage:
keyboardEditText.listener = object : KeyboardEditText.Listener {
override fun onImeBack(editText: KeyboardEditText) {
//Back detected
}
}
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