@@ -79,9 +79,20 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega
7979 // it is associated with(e.g if a platform view creates other views in the same virtual display.
8080 private final HashMap <Context , View > contextToPlatformView ;
8181
82- private final SparseArray <PlatformViewsChannel .PlatformViewCreationRequest > platformViewRequests ;
82+ // The view returned by `PlatformView#getView()`.
83+ //
84+ // This only applies to hybrid composition.
8385 private final SparseArray <View > platformViews ;
84- private final SparseArray <FlutterMutatorView > mutatorViews ;
86+
87+ // The platform view parent that is appended to `FlutterView`.
88+ // If an entry in `platformViews` doesn't have an entry in this array, the platform view isn't
89+ // in the view hierarchy.
90+ //
91+ // This view provides a wrapper that applies scene builder operations to the platform view.
92+ // For example, a transform matrix, or setting opacity on the platform view layer.
93+ //
94+ // This is only applies to hybrid composition.
95+ private final SparseArray <FlutterMutatorView > platformViewParent ;
8596
8697 // Map of unique IDs to views that render overlay layers.
8798 private final SparseArray <FlutterImageView > overlayLayerViews ;
@@ -120,12 +131,17 @@ public void disposeAndroidViewForPlatformView(int viewId) {
120131 }
121132
122133 final View platformView = platformViews .get (viewId );
134+ final FlutterMutatorView parentView = platformViewParent .get (viewId );
123135 if (platformView != null ) {
124- final FlutterMutatorView mutatorView = mutatorViews . get ( viewId );
125- mutatorView .removeView (platformView );
126- (( FlutterView ) flutterView ). removeView ( mutatorView );
136+ if ( parentView != null ) {
137+ parentView .removeView (platformView );
138+ }
127139 platformViews .remove (viewId );
128- mutatorViews .remove (viewId );
140+ }
141+
142+ if (parentView != null ) {
143+ ((FlutterView ) flutterView ).removeView (parentView );
144+ platformViewParent .remove (viewId );
129145 }
130146 }
131147
@@ -380,7 +396,7 @@ public PlatformViewsController() {
380396
381397 platformViewRequests = new SparseArray <>();
382398 platformViews = new SparseArray <>();
383- mutatorViews = new SparseArray <>();
399+ platformViewParent = new SparseArray <>();
384400
385401 motionEventTracker = MotionEventTracker .getInstance ();
386402 }
@@ -654,52 +670,20 @@ void initializePlatformViewIfNeeded(int viewId) {
654670 if (platformViews .get (viewId ) != null ) {
655671 return ;
656672 }
657-
658673 PlatformViewsChannel .PlatformViewCreationRequest request = platformViewRequests .get (viewId );
659674 if (request == null ) {
660675 throw new IllegalStateException (
661676 "Platform view hasn't been initialized from the platform view channel." );
662677 }
663-
664- if (!validateDirection (request .direction )) {
665- throw new IllegalStateException (
666- "Trying to create a view with unknown direction value: "
667- + request .direction
668- + "(view id: "
669- + viewId
670- + ")" );
671- }
672-
673- PlatformViewFactory factory = registry .getFactory (request .viewType );
674- if (factory == null ) {
675- throw new IllegalStateException (
676- "Trying to create a platform view of unregistered type: " + request .viewType );
677- }
678-
679- Object createParams = null ;
680- if (request .params != null ) {
681- createParams = factory .getCreateArgsCodec ().decodeMessage (request .params );
682- }
683-
684- PlatformView platformView = factory .create (context , viewId , createParams );
685- View view = platformView .getView ();
686-
687- if (view == null ) {
688- throw new IllegalStateException (
689- "PlatformView#getView() returned null, but an Android view reference was expected." );
690- }
691- if (view .getParent () != null ) {
692- throw new IllegalStateException (
693- "The Android view returned from PlatformView#getView() was already added to a parent view." );
678+ if (platformViewParent .get (viewId ) != null ) {
679+ return ;
694680 }
695- platformViews .put (viewId , view );
696-
697- FlutterMutatorView mutatorView =
681+ final FlutterMutatorView parentView =
698682 new FlutterMutatorView (
699683 context , context .getResources ().getDisplayMetrics ().density , androidTouchProcessor );
700- mutatorViews .put (viewId , mutatorView );
701- mutatorView .addView (view );
702- ((FlutterView ) flutterView ).addView (mutatorView );
684+ platformViewParent .put (viewId , parentView );
685+ parentView .addView (view );
686+ ((FlutterView ) flutterView ).addView (parentView );
703687 }
704688
705689 public void attachToFlutterRenderer (FlutterRenderer flutterRenderer ) {
@@ -718,13 +702,14 @@ public void onDisplayPlatformView(
718702 initializeRootImageViewIfNeeded ();
719703 initializePlatformViewIfNeeded (viewId );
720704
721- FlutterMutatorView mutatorView = mutatorViews .get (viewId );
722- mutatorView .readyToDisplay (mutatorsStack , x , y , width , height );
723- mutatorView .setVisibility (View .VISIBLE );
724- mutatorView .bringToFront ();
705+ final FlutterMutatorView parentView = platformViewParent .get (viewId );
706+ parentView .readyToDisplay (mutatorsStack , x , y , width , height );
707+ parentView .setVisibility (View .VISIBLE );
708+ parentView .bringToFront ();
725709
726- FrameLayout .LayoutParams layoutParams = new FrameLayout .LayoutParams (viewWidth , viewHeight );
727- View platformView = platformViews .get (viewId );
710+ final FrameLayout .LayoutParams layoutParams =
711+ new FrameLayout .LayoutParams (viewWidth , viewHeight );
712+ final View platformView = platformViews .get (viewId );
728713 platformView .setLayoutParams (layoutParams );
729714 platformView .bringToFront ();
730715 currentFrameUsedPlatformViewIds .add (viewId );
@@ -733,7 +718,7 @@ public void onDisplayPlatformView(
733718 public void onDisplayOverlaySurface (int id , int x , int y , int width , int height ) {
734719 initializeRootImageViewIfNeeded ();
735720
736- FlutterImageView overlayView = overlayLayerViews .get (id );
721+ final FlutterImageView overlayView = overlayLayerViews .get (id );
737722 if (overlayView .getParent () == null ) {
738723 ((FlutterView ) flutterView ).addView (overlayView );
739724 }
@@ -776,19 +761,19 @@ public void onEndFrame() {
776761 // If one of the surfaces doesn't have an image, the frame may be incomplete and must be
777762 // dropped.
778763 // For example, a toolbar widget painted by Flutter may not be rendered.
779- boolean isFrameRenderedUsingImageReaders =
764+ final boolean isFrameRenderedUsingImageReaders =
780765 flutterViewConvertedToImageView && view .acquireLatestImageViewFrame ();
781766 finishFrame (isFrameRenderedUsingImageReaders );
782767 }
783768
784769 private void finishFrame (boolean isFrameRenderedUsingImageReaders ) {
785770 for (int i = 0 ; i < overlayLayerViews .size (); i ++) {
786- int overlayId = overlayLayerViews .keyAt (i );
787- FlutterImageView overlayView = overlayLayerViews .valueAt (i );
771+ final int overlayId = overlayLayerViews .keyAt (i );
772+ final FlutterImageView overlayView = overlayLayerViews .valueAt (i );
788773
789774 if (currentFrameUsedOverlayLayerIds .contains (overlayId )) {
790775 ((FlutterView ) flutterView ).attachOverlaySurfaceToRender (overlayView );
791- boolean didAcquireOverlaySurfaceImage = overlayView .acquireLatestImage ();
776+ final boolean didAcquireOverlaySurfaceImage = overlayView .acquireLatestImage ();
792777 isFrameRenderedUsingImageReaders &= didAcquireOverlaySurfaceImage ;
793778 } else {
794779 // If the background surface isn't rendered by the image view, then the
@@ -802,22 +787,20 @@ private void finishFrame(boolean isFrameRenderedUsingImageReaders) {
802787 }
803788 }
804789
805- for (int i = 0 ; i < platformViews .size (); i ++) {
806- int viewId = platformViews .keyAt (i );
807- View platformView = platformViews .get (viewId );
808- View mutatorView = mutatorViews .get (viewId );
790+ for (int i = 0 ; i < platformViewParent .size (); i ++) {
791+ final int viewId = platformViewParent .keyAt (i );
792+ final View parentView = platformViewParent .get (viewId );
809793
810794 // Show platform views only if the surfaces have images available in this frame,
811795 // and if the platform view is rendered in this frame.
796+ // The platform view is appended to a mutator view.
812797 //
813798 // Otherwise, hide the platform view, but don't remove it from the view hierarchy yet as
814799 // they are removed when the framework diposes the platform view widget.
815800 if (isFrameRenderedUsingImageReaders && currentFrameUsedPlatformViewIds .contains (viewId )) {
816- platformView .setVisibility (View .VISIBLE );
817- mutatorView .setVisibility (View .VISIBLE );
801+ parentView .setVisibility (View .VISIBLE );
818802 } else {
819- platformView .setVisibility (View .GONE );
820- mutatorView .setVisibility (View .GONE );
803+ parentView .setVisibility (View .GONE );
821804 }
822805 }
823806 }
0 commit comments