Mobile

Flutter app renders black screen on foldable Android phones after fold/unfold events — display density and PlatformView mismatch

Environment

Environment

Flutter 3.3 app compiled in release mode, target device: Android foldable (Android 12L), app uses a mix of Flutter widgets and an embedded PlatformView for a native video player. Reproducible on Samsung Galaxy Z Fold 3 and in Foldable emulator configuration in Android Studio.

Symptoms

Symptoms

User launches app on folded device: UI renders normally. On unfolding the device, the app surface goes completely black (no UI), audio continues if video was playing. Closing and reopening the app sometimes restores UI; rotating device does not help. The black screen typically appears only when a PlatformView was visible during the fold/unfold transition.

Observations

Observations

ADB logcat shows SurfaceControl errors and messages about 'Windowless surface destroyed' and 'composite failed' around the time of folding. Flutter engine logs indicate a GPU surface reconfiguration attempt and a mismatch between physical display metrics and Flutter's rasterizer surface size. Reproduces only in release builds; debug builds with observatory remain stable (but have different timing). Using a pure Flutter video player (no PlatformView) reduced frequency but did not eliminate the problem. The device reports a configuration change with a new displayRect and density when unfolded.

Already attempted

Already attempted

Updated flutter channel to latest stable, added handling for WidgetsBindingObserver didChangeMetrics to force rebuild on metrics change, attempted to recreate PlatformView onActivityRecreate — no consistent fix. Tested toggling Android:hardwareAccelerated and different Flutter embeddings (v2) without luck. Reproduced in emulator fold events and on hardware.

Question

Question

What causes a black Flutter surface after fold/unfold transitions on Android foldable devices, especially when PlatformView is present, and what reversible application or embedding-level strategies can be used to force a safe surface reattachment without losing user state? When should this be escalated to Flutter engine or OEM bug trackers?

COMMUNITY RESPONSES

Verified community troubleshooting

0 replies

No answers yet..

Showing 0 of 0 community responses
AI DIAGNOSTICS

Incident analysis

Updated 1w ago• Trouble ID

Most likely causes

Race between Android window surface recreation on configuration change and Flutter engine attempting to reattach PlatformView, leaving an uninitialized compositor surface. 90%
Incorrect handling of display density/size changes in the embedding that does not recreate or resize the FlutterSurfaceView properly after fold transitions. 85%
PlatformView implementation (native video player) not handling on surfaceDestroyed/on surfaceCreated lifecycle during configuration changes. 70%

Summary

Foldable transitions change physical display metrics and can trigger the Android window to recreate surfaces. PlatformViews create a separate native surface layer which the Flutter compositor must embed; when display metrics change or surfaces are destroyed and recreated rapidly, the engine may fail to rebind the PlatformView to the new compositor surface, leaving a black region. Release builds' performance optimizations and differences in timing can expose race conditions. The presence of SurfaceControl errors in logs and successful debug-mode runs indicate a potential race or missing lifecycle handling in the Flutter embedding or the platform view implementation.

Suggested Fixes

Diagnostic step 1
Capture detailed logcat including Flutter engine logs and SurfaceControl messages during a reproduce; include timestamps and stack traces for surface creation/destruction events and redact sensitive tokens.
Diagnostic step 2
Implement a robust WidgetsBindingObserver.didChangeMetrics handler that forces a safe reinitialize of the PlatformView: stop the native view, call setState to remove it from the widget tree, schedule a delayed re-add after 100–250 ms to allow the system to recreate surfaces (test varying delays).
Diagnostic step 3
In the embedding (MainActivity), listen for onConfigurationChanged and forward events to the Flutter engine; ensure FlutterActivity is using the v2 embedding and PlatformView lifecycle helpers.

Continue troubleshooting

Matched from the title, description and tags