From aa2c682a863d97e3567b8ba793d99657f7643764 Mon Sep 17 00:00:00 2001 From: Oleksandr Melnykov Date: Thu, 11 Jul 2019 03:48:22 -0700 Subject: [PATCH] Fix IllegalStateException in TextView.onEditorAction() Summary: This diff fixes a crash caused by an IllegalStateException thrown from the `TextView.onEditorAction()`. This could happen if we don't return false from the `OnEditorActionListener.onEditorAction()` and Android will fallback to the default behaviour, which will try to search and focus the next/previous view in case of `EditorInfo.IME_ACTION_NEXT` or `EditorInfo.IME_ACTION_PREVIOUS` accordingly. Because ReactEditText prevents requesting focus from Android (`ReactEditText.requestFocus()` returns false), the following piece of code from `TextView.onEditorAction()` will crash the app: ``` } else if (actionCode == EditorInfo.IME_ACTION_PREVIOUS) { View v = focusSearch(FOCUS_BACKWARD); if (v != null) { if (!v.requestFocus(FOCUS_BACKWARD)) { throw new IllegalStateException("focus search returned a view " + "that wasn't able to take focus!"); } } return; } else if (actionCode == EditorInfo.IME_ACTION_DONE) { InputMethodManager imm = InputMethodManager.peekInstance(); if (imm != null && imm.isActive(this)) { imm.hideSoftInputFromWindow(getWindowToken(), 0); } return; } ``` To prevent this we have to catch `EditorInfo.IME_ACTION_NEXT` and `EditorInfo.IME_ACTION_PREVIOUS` inside `OnEditorActionListener.onEditorAction()` and prevent the default Android behaviour. Reviewed By: mdvacca Differential Revision: D16180306 fbshipit-source-id: 6118257c16a7a4a205ae05da671cd76d3a18d565 --- .../react/views/textinput/ReactEditText.java | 2 +- .../textinput/ReactTextInputManager.java | 25 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java index b86fc5067ae..abc92b4b14b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java @@ -499,7 +499,7 @@ public class ReactEditText extends EditText { return mTextWatcherDelegator; } - private boolean isMultiline() { + /* package */ boolean isMultiline() { return (getInputType() & InputType.TYPE_TEXT_FLAG_MULTI_LINE) != 0; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index 0fd50130d25..d3ce4db4dc3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -6,8 +6,6 @@ */ package com.facebook.react.views.textinput; -import static android.view.View.FOCUS_FORWARD; - import android.graphics.PorterDuff; import android.graphics.Typeface; import android.graphics.drawable.Drawable; @@ -904,11 +902,9 @@ public class ReactTextInputManager extends BaseViewManager 0 || actionId == EditorInfo.IME_NULL) { + if ((actionId & EditorInfo.IME_MASK_ACTION) != 0 || actionId == EditorInfo.IME_NULL) { boolean blurOnSubmit = editText.getBlurOnSubmit(); - boolean isMultiline = - ((editText.getInputType() & InputType.TYPE_TEXT_FLAG_MULTI_LINE) != 0); + boolean isMultiline = editText.isMultiline(); // Motivation: // * blurOnSubmit && isMultiline => Clear focus; prevent default behaviour (return @@ -931,13 +927,20 @@ public class ReactTextInputManager extends BaseViewManager