Description
On Android 12 (Samsung One UI 4.1, targetSdk 36 / edge-to-edge enabled by app config), a single touch on a screen containing a focusable TextInput inside a KeyboardAvoidingView triggers a self-sustaining relayout loop that never stops on its own — the screen visibly oscillates in size ("zoom in/out") and becomes unusable. The loop continues indefinitely with no further user input.
Confirmed via adb logcat that after the triggering touch, relayouts keep firing every ~250-300ms indefinitely (tested for 90+ seconds with zero additional touch events) in a tight repeating pattern:
W ReactNative: Attempt to set local data for view with unknown tag: -1 (x6, sometimes real tags e.g. 32749/32767)
W ReactNative: StatusBarModule: Ignored status bar change, current activity is edge-to-edge. (x2)
V WindowManager: Relayout Window{... MainActivity}: viewVisibility=0 req=1080x2400 d0
Investigation done to rule out app-level causes
I methodically tested and ruled out (each with fresh adb logcat evidence, real touch events confirmed captured):
StatusBar from react-native vs expo-status-bar — no difference.
KeyboardAvoidingView behavior="height" vs undefined on Android — no difference.
@sentry/react-native's mobileReplayIntegration() — removed, no difference.
@sentry/react-native entirely disabled (no Sentry.init() call at all) — loop still occurs identically (118 relayouts / 236 status-bar-ignored / 684 tag warnings in a 40s window with 30 real touches captured), definitively ruling out Sentry.
- Confirmed the "Ignored status bar change, current activity is edge-to-edge" log line originates from
StatusBarModule.setColor()/setTranslucent() in react-native core, not setStyle() — meaning no JS-level <StatusBar> prop change is the trigger.
This points to native insets/window-traits handling inside react-native-screens's native-stack (used via expo-router) as the source, independent of any app-level JS code.
Steps to reproduce
- Expo SDK 54 project,
expo-router, Legacy Architecture (newArchEnabled: false), targetSdk/compileSdk 36 (edge-to-edge enforced).
- A route inside a
Stack (screenOptions={{ headerShown: false }}) rendering a screen with a TextInput wrapped in KeyboardAvoidingView.
- Run on a physical Android 12 device (Samsung Galaxy M51 / SM-M515F, One UI 4.1) via
expo run:android (also reproduced on a signed release/preview APK, not just dev client).
- Tap into the
TextInput (or tap anywhere on the screen) once.
- Observe: the screen keeps resizing/relayouting continuously with no further interaction;
adb logcat shows the pattern above repeating indefinitely.
Environment
- react-native-screens: 4.16.0
- react-native: 0.81.5
- expo: 54.0.35 (SDK 54)
- react-native-safe-area-context: 5.6.0 (~)
- Architecture: Legacy (Paper) —
newArchEnabled: false
- targetSdk / compileSdk: 36
- Device: Samsung Galaxy M51 (SM-M515F), Android 12 (API 31), One UI 4.1, security patch 2024-05-01
- Also reproduces on a signed preview/production-style APK, not only debug/dev-client builds
Expected behavior
Screen renders and responds to touch normally; no self-sustaining relayout loop after a single touch.
Actual behavior
Screen becomes unusable (visually "zooming" in/out) after a single touch, requiring the app to be force-closed.
Happy to provide a minimal reproduction repo or additional adb logcat captures if useful.
Description
On Android 12 (Samsung One UI 4.1, targetSdk 36 / edge-to-edge enabled by app config), a single touch on a screen containing a focusable
TextInputinside aKeyboardAvoidingViewtriggers a self-sustaining relayout loop that never stops on its own — the screen visibly oscillates in size ("zoom in/out") and becomes unusable. The loop continues indefinitely with no further user input.Confirmed via
adb logcatthat after the triggering touch, relayouts keep firing every ~250-300ms indefinitely (tested for 90+ seconds with zero additional touch events) in a tight repeating pattern:Investigation done to rule out app-level causes
I methodically tested and ruled out (each with fresh
adb logcatevidence, real touch events confirmed captured):StatusBarfromreact-nativevsexpo-status-bar— no difference.KeyboardAvoidingViewbehavior="height"vsundefinedon Android — no difference.@sentry/react-native'smobileReplayIntegration()— removed, no difference.@sentry/react-nativeentirely disabled (noSentry.init()call at all) — loop still occurs identically (118 relayouts / 236 status-bar-ignored / 684 tag warnings in a 40s window with 30 real touches captured), definitively ruling out Sentry.StatusBarModule.setColor()/setTranslucent()inreact-nativecore, notsetStyle()— meaning no JS-level<StatusBar>prop change is the trigger.This points to native insets/window-traits handling inside
react-native-screens's native-stack (used viaexpo-router) as the source, independent of any app-level JS code.Steps to reproduce
expo-router, Legacy Architecture (newArchEnabled: false),targetSdk/compileSdk36 (edge-to-edge enforced).Stack(screenOptions={{ headerShown: false }}) rendering a screen with aTextInputwrapped inKeyboardAvoidingView.expo run:android(also reproduced on a signed release/preview APK, not just dev client).TextInput(or tap anywhere on the screen) once.adb logcatshows the pattern above repeating indefinitely.Environment
newArchEnabled: falseExpected behavior
Screen renders and responds to touch normally; no self-sustaining relayout loop after a single touch.
Actual behavior
Screen becomes unusable (visually "zooming" in/out) after a single touch, requiring the app to be force-closed.
Happy to provide a minimal reproduction repo or additional
adb logcatcaptures if useful.