diff --git a/engine/src/flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java b/engine/src/flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java index 37986439e41..46eb7182bce 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java @@ -68,6 +68,7 @@ public class FlutterView extends FrameLayout { // Internal view hierarchy references. @Nullable private FlutterRenderer.RenderSurface renderSurface; + private boolean didRenderFirstFrame; // Connections to a Flutter execution context. @Nullable @@ -97,6 +98,13 @@ public class FlutterView extends FrameLayout { } }; + private final OnFirstFrameRenderedListener onFirstFrameRenderedListener = new OnFirstFrameRenderedListener() { + @Override + public void onFirstFrameRendered() { + didRenderFirstFrame = true; + } + }; + /** * Constructs a {@code FlutterView} programmatically, without any XML attributes. *
@@ -171,11 +179,34 @@ public class FlutterView extends FrameLayout { break; } + // Register a listener for the first frame render event to set didRenderFirstFrame. + renderSurface.addOnFirstFrameRenderedListener(onFirstFrameRenderedListener); + // FlutterView needs to be focusable so that the InputMethodManager can interact with it. setFocusable(true); setFocusableInTouchMode(true); } + /** + * Returns true if an attached {@link FlutterEngine} has rendered at least 1 frame to this + * {@code FlutterView}. + *
+ * Returns false if no {@link FlutterEngine} is attached. + *
+ * This flag is specific to a given {@link FlutterEngine}. The following hypothetical timeline + * demonstrates how this flag changes over time. + *