4444public class PlatformViewsController implements PlatformViewsAccessibilityDelegate {
4545 private static final String TAG = "PlatformViewsController" ;
4646
47- // API level 20 is required for VirtualDisplay#setSurface which we use when resizing a platform
48- // view.
49- private static final int MINIMAL_SDK = Build .VERSION_CODES .KITKAT_WATCH ;
50-
5147 private final PlatformViewRegistryImpl registry ;
5248
5349 // The context of the Activity or Fragment hosting the render target for the Flutter engine.
@@ -80,6 +76,9 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega
8076 // it is associated with(e.g if a platform view creates other views in the same virtual display.
8177 private final HashMap <Context , View > contextToPlatformView ;
8278
79+ private final SparseArray <PlatformViewsChannel .PlatformViewCreationRequest > platformViewRequests ;
80+ private final SparseArray <View > platformViews ;
81+
8382 // Map of unique IDs to views that render overlay layers.
8483 private final SparseArray <FlutterImageView > overlayLayerViews ;
8584
@@ -94,12 +93,34 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega
9493
9594 private final PlatformViewsChannel .PlatformViewsHandler channelHandler =
9695 new PlatformViewsChannel .PlatformViewsHandler () {
97- @ TargetApi ( Build . VERSION_CODES . JELLY_BEAN_MR1 )
96+
9897 @ Override
99- public long createPlatformView (
98+ public void createAndroidViewForPlatformView (
10099 @ NonNull PlatformViewsChannel .PlatformViewCreationRequest request ) {
101- ensureValidAndroidVersion ();
100+ // API level 19 is required for android.graphics.ImageReader.
101+ ensureValidAndroidVersion (Build .VERSION_CODES .KITKAT );
102+ platformViewRequests .put (request .viewId , request );
103+ }
104+
105+ @ Override
106+ public void disposeAndroidViewForPlatformView (int viewId ) {
107+ // Hybrid view.
108+ if (platformViewRequests .get (viewId ) != null ) {
109+ platformViewRequests .remove (viewId );
110+ }
111+ if (platformViews .get (viewId ) != null ) {
112+ ((FlutterView ) flutterView ).addView (platformViews .get (viewId ));
113+ platformViews .remove (viewId );
114+ }
115+ }
102116
117+ @ Override
118+ public long createVirtualDisplayForPlatformView (
119+ @ NonNull PlatformViewsChannel .PlatformViewCreationRequest request ) {
120+ // API level 20 is required for VirtualDisplay#setSurface which we use when resizing a
121+ // platform
122+ // view.
123+ ensureValidAndroidVersion (Build .VERSION_CODES .KITKAT_WATCH );
103124 if (!validateDirection (request .direction )) {
104125 throw new IllegalStateException (
105126 "Trying to create a view with unknown direction value: "
@@ -171,9 +192,8 @@ public long createPlatformView(
171192 }
172193
173194 @ Override
174- public void disposePlatformView (int viewId ) {
175- ensureValidAndroidVersion ();
176-
195+ public void disposeVirtualDisplayForPlatformView (int viewId ) {
196+ ensureValidAndroidVersion (Build .VERSION_CODES .KITKAT_WATCH );
177197 VirtualDisplayController vdController = vdControllers .get (viewId );
178198 if (vdController == null ) {
179199 throw new IllegalStateException (
@@ -193,7 +213,7 @@ public void disposePlatformView(int viewId) {
193213 public void resizePlatformView (
194214 @ NonNull PlatformViewsChannel .PlatformViewResizeRequest request ,
195215 @ NonNull Runnable onComplete ) {
196- ensureValidAndroidVersion ();
216+ ensureValidAndroidVersion (Build . VERSION_CODES . KITKAT_WATCH );
197217
198218 final VirtualDisplayController vdController = vdControllers .get (request .viewId );
199219 if (vdController == null ) {
@@ -224,8 +244,6 @@ public void run() {
224244
225245 @ Override
226246 public void onTouch (@ NonNull PlatformViewsChannel .PlatformViewTouch touch ) {
227- ensureValidAndroidVersion ();
228-
229247 float density = context .getResources ().getDisplayMetrics ().density ;
230248 PointerProperties [] pointerProperties =
231249 parsePointerPropertiesList (touch .rawPointerPropertiesList )
@@ -256,14 +274,12 @@ public void onTouch(@NonNull PlatformViewsChannel.PlatformViewTouch touch) {
256274 touch .source ,
257275 touch .flags );
258276
277+ ensureValidAndroidVersion (Build .VERSION_CODES .KITKAT_WATCH );
259278 vdControllers .get (touch .viewId ).dispatchTouchEvent (event );
260279 }
261280
262- @ TargetApi (Build .VERSION_CODES .JELLY_BEAN_MR1 )
263281 @ Override
264282 public void setDirection (int viewId , int direction ) {
265- ensureValidAndroidVersion ();
266-
267283 if (!validateDirection (direction )) {
268284 throw new IllegalStateException (
269285 "Trying to set unknown direction value: "
@@ -273,6 +289,7 @@ public void setDirection(int viewId, int direction) {
273289 + ")" );
274290 }
275291
292+ ensureValidAndroidVersion (Build .VERSION_CODES .KITKAT_WATCH );
276293 View view = vdControllers .get (viewId ).getView ();
277294 if (view == null ) {
278295 throw new IllegalStateException (
@@ -284,17 +301,18 @@ public void setDirection(int viewId, int direction) {
284301
285302 @ Override
286303 public void clearFocus (int viewId ) {
304+ ensureValidAndroidVersion (Build .VERSION_CODES .KITKAT_WATCH );
287305 View view = vdControllers .get (viewId ).getView ();
288306 view .clearFocus ();
289307 }
290308
291- private void ensureValidAndroidVersion () {
292- if (Build .VERSION .SDK_INT < MINIMAL_SDK ) {
309+ private void ensureValidAndroidVersion (int minSdkVersion ) {
310+ if (Build .VERSION .SDK_INT < minSdkVersion ) {
293311 throw new IllegalStateException (
294312 "Trying to use platform views with API "
295313 + Build .VERSION .SDK_INT
296314 + ", required API level is: "
297- + MINIMAL_SDK );
315+ + minSdkVersion );
298316 }
299317 }
300318 };
@@ -306,6 +324,9 @@ public PlatformViewsController() {
306324 contextToPlatformView = new HashMap <>();
307325 overlayLayerViews = new SparseArray <>();
308326 currentFrameUsedOverlayLayerIds = new HashSet <>();
327+
328+ platformViewRequests = new SparseArray <>();
329+ platformViews = new SparseArray <>();
309330 }
310331
311332 /**
@@ -565,13 +586,60 @@ private void initializeRootImageViewIfNeeded() {
565586 }
566587 }
567588
589+ private void initializePlatformViewIfNeeded (int viewId ) {
590+ if (platformViews .get (viewId ) != null ) {
591+ return ;
592+ }
593+
594+ PlatformViewsChannel .PlatformViewCreationRequest request = platformViewRequests .get (viewId );
595+ if (request == null ) {
596+ throw new IllegalStateException (
597+ "Platform view hasn't been initialized from the platform view channel." );
598+ }
599+
600+ if (!validateDirection (request .direction )) {
601+ throw new IllegalStateException (
602+ "Trying to create a view with unknown direction value: "
603+ + request .direction
604+ + "(view id: "
605+ + viewId
606+ + ")" );
607+ }
608+
609+ PlatformViewFactory factory = registry .getFactory (request .viewType );
610+ if (factory == null ) {
611+ throw new IllegalStateException (
612+ "Trying to create a platform view of unregistered type: " + request .viewType );
613+ }
614+
615+ Object createParams = null ;
616+ if (request .params != null ) {
617+ createParams = factory .getCreateArgsCodec ().decodeMessage (request .params );
618+ }
619+
620+ PlatformView platformView = factory .create (context , viewId , createParams );
621+ View view = platformView .getView ();
622+ platformViews .put (viewId , view );
623+
624+ ((FlutterView ) flutterView ).addView (view );
625+ }
626+
568627 public void onDisplayPlatformView (int viewId , int x , int y , int width , int height ) {
569628 initializeRootImageViewIfNeeded ();
570- // TODO: Implement this method. https://github.com/flutter/flutter/issues/58288
629+ initializePlatformViewIfNeeded (viewId );
630+
631+ View platformView = platformViews .get (viewId );
632+ FrameLayout .LayoutParams layoutParams = new FrameLayout .LayoutParams ((int ) width , (int ) height );
633+ layoutParams .leftMargin = (int ) x ;
634+ layoutParams .topMargin = (int ) y ;
635+ platformView .setLayoutParams (layoutParams );
636+ platformView .setVisibility (View .VISIBLE );
637+ platformView .bringToFront ();
571638 }
572639
573640 public void onDisplayOverlaySurface (int id , int x , int y , int width , int height ) {
574641 initializeRootImageViewIfNeeded ();
642+
575643 FlutterImageView overlayView = overlayLayerViews .get (id );
576644 if (overlayView .getParent () == null ) {
577645 ((FlutterView ) flutterView ).addView (overlayView );
0 commit comments