Fix: TextField not always properly visible after keyboard opens
requestRectangleOnScreen may modify the input Rect. When it's called
repeatedly, we may encounter some unexpected issues. This can be one
of the reasons that TextInputService.notifyFocusedRect sometimes doesn't
work.
Before this change,it's very likely that notifyFocusedRect doesn't work
when the keyboard is opened for the first time. After the fix, it no
longer happens in the demo APP.
Bug: 190539358
Test: ./gradlew test
Test: ./gradlew compose:ui:ui-text:connectedAndroidTest
Test: manually tested in demo app
Change-Id: I859a4ab7be2fb0b4bda808646027cf3934af2196
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
index e61215c..333a055 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
@@ -70,7 +70,11 @@
private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
// focusedRect is null if there is not ongoing text input session. So safe to request
// latest focused rectangle whenever global layout has changed.
- focusedRect?.let { view.requestRectangleOnScreen(it) }
+ focusedRect?.let {
+ // Notice that view.requestRectangleOnScreen may modify the input Rect, we have to
+ // create another Rect and then pass it.
+ view.requestRectangleOnScreen(android.graphics.Rect(it))
+ }
}
internal constructor(view: View) : this(view, InputMethodManagerImpl(view.context))
@@ -236,7 +240,11 @@
// Even if we miss all the timing of requesting rectangle during initial text field focus,
// focused rectangle will be requested when software keyboard has shown.
if (ic == null) {
- view.requestRectangleOnScreen(focusedRect)
+ focusedRect?.let {
+ // Notice that view.requestRectangleOnScreen may modify the input Rect, we have to
+ // create another Rect and then pass it.
+ view.requestRectangleOnScreen(android.graphics.Rect(it))
+ }
}
}
}