Skip to content

Commit 241d157

Browse files
authored
fix: do not overcast to ReactEditText (#776)
## 📜 Description Cast to base `EditText` class whenever it's possible. ## 💡 Motivation and Context If you deal with native SDKs (i. e. Stripe), then in such SDKs they may inherit their component from native `EditText` and simply expose them to JS layer. Casting to `ReactEditText` will eventually fail and part of this library will not be working (everything about tracking focused input). So in this PR I decided to cast everything to `EditText`. Conditional casting will be only in two places `focus` method and in reflection in `addTextChangedListener`. But in the last method I still can get a crash: `Expected receiver of type com.facebook.react.views.textinput.ReactEditText, but got com.stripe.android.view.CardNumberEditText`, so to overcome this problem I decided to handle that exception and call original method. Resolves android issue in #775 ## 📢 Changelog <!-- High level overview of important changes --> <!-- For example: fixed status bar manipulation; added new types declarations; --> <!-- If your changes don't affect one of platform/language below - then remove this platform/language --> ### Android - cast to `EditText` instead of `ReactEditText` whenever it's possible; - handle `IllegalArgumentException` in `addOnTextChangedListener`. ## 🤔 How Has This Been Tested? Tested on Medium Phone API 35 emulator. ## 📸 Screenshots (if appropriate): Sorry, but emulator is really laggy 😬 https://github.com/user-attachments/assets/08024fcc-6233-4fca-97f9-d5c6dfdfc479 ## 📝 Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was changed
1 parent 4f1a798 commit 241d157

File tree

3 files changed

+14
-7
lines changed

3 files changed

+14
-7
lines changed

android/src/main/java/com/reactnativekeyboardcontroller/extensions/EditText.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ fun EditText.addOnTextChangedListener(action: (String) -> Unit): TextWatcher {
7979
Logger.w(javaClass.simpleName, "Can not attach listener because casting failed: ${e.message}")
8080
} catch (e: NoSuchFieldException) {
8181
Logger.w(javaClass.simpleName, "Can not attach listener because field `mListeners` not found: ${e.message}")
82+
} catch (e: IllegalArgumentException) {
83+
Logger.w(
84+
javaClass.simpleName,
85+
"Can not attach listener to be the first in the list: ${e.message}. Attaching to the end...",
86+
)
87+
// it's plain EditText - it doesn't have the same problem as ReactEditText
88+
this.addTextChangedListener(listener)
8289
}
8390

8491
return listener
@@ -147,7 +154,7 @@ val EditText?.keyboardType: String
147154
}
148155

149156
class KeyboardControllerSelectionWatcher(
150-
private val editText: ReactEditText,
157+
private val editText: EditText,
151158
private val action: (start: Int, end: Int, startX: Double, startY: Double, endX: Double, endY: Double) -> Unit,
152159
) {
153160
private var lastSelectionStart: Int = -1
@@ -233,7 +240,7 @@ class KeyboardControllerSelectionWatcher(
233240
}
234241
}
235242

236-
fun ReactEditText.addOnSelectionChangedListener(
243+
fun EditText.addOnSelectionChangedListener(
237244
action: (start: Int, end: Int, startX: Double, startY: Double, endX: Double, endY: Double) -> Unit,
238245
): () -> Unit {
239246
val listener = KeyboardControllerSelectionWatcher(this, action)

android/src/main/java/com/reactnativekeyboardcontroller/listeners/FocusedInputObserver.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import android.text.TextWatcher
44
import android.view.View
55
import android.view.View.OnLayoutChangeListener
66
import android.view.ViewTreeObserver.OnGlobalFocusChangeListener
7+
import android.widget.EditText
78
import com.facebook.react.bridge.Arguments
89
import com.facebook.react.uimanager.ThemedReactContext
910
import com.facebook.react.uimanager.UIManagerHelper
10-
import com.facebook.react.views.textinput.ReactEditText
1111
import com.facebook.react.views.view.ReactViewGroup
1212
import com.reactnativekeyboardcontroller.events.FocusedInputLayoutChangedEvent
1313
import com.reactnativekeyboardcontroller.events.FocusedInputLayoutChangedEventData
@@ -46,7 +46,7 @@ class FocusedInputObserver(
4646
private val surfaceId = UIManagerHelper.getSurfaceId(view)
4747

4848
// state variables
49-
private var lastFocusedInput: ReactEditText? = null
49+
private var lastFocusedInput: EditText? = null
5050
private var lastEventDispatched: FocusedInputLayoutChangedEventData = noFocusedInputEvent
5151
private var textWatcher: TextWatcher? = null
5252
private var selectionSubscription: (() -> Unit)? = null
@@ -105,7 +105,7 @@ class FocusedInputObserver(
105105
selectionSubscription?.invoke()
106106
lastFocusedInput = null
107107
}
108-
if (newFocus is ReactEditText) {
108+
if (newFocus is EditText) {
109109
lastFocusedInput = newFocus
110110
newFocus.addOnLayoutChangeListener(layoutListener)
111111
this.syncUpLayout()

android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.reactnativekeyboardcontroller.listeners
22

33
import android.view.View
44
import android.view.ViewTreeObserver.OnGlobalFocusChangeListener
5+
import android.widget.EditText
56
import androidx.core.graphics.Insets
67
import androidx.core.view.OnApplyWindowInsetsListener
78
import androidx.core.view.ViewCompat
@@ -11,7 +12,6 @@ import com.facebook.react.bridge.Arguments
1112
import com.facebook.react.bridge.WritableMap
1213
import com.facebook.react.uimanager.ThemedReactContext
1314
import com.facebook.react.uimanager.UIManagerHelper
14-
import com.facebook.react.views.textinput.ReactEditText
1515
import com.facebook.react.views.view.ReactViewGroup
1616
import com.reactnativekeyboardcontroller.constants.Keyboard
1717
import com.reactnativekeyboardcontroller.events.KeyboardTransitionEvent
@@ -67,7 +67,7 @@ class KeyboardAnimationCallback(
6767
// listeners
6868
private val focusListener =
6969
OnGlobalFocusChangeListener { oldFocus, newFocus ->
70-
if (newFocus is ReactEditText) {
70+
if (newFocus is EditText) {
7171
viewTagFocused = newFocus.id
7272

7373
// keyboard is visible and focus has been changed

0 commit comments

Comments
 (0)