Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
61c30eed
Unverified
Commit
61c30eed
authored
Mar 29, 2022
by
Emmanuel Garcia
Committed by
GitHub
Mar 29, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reland: "Use texture layer when displaying an Android view" (#100934)
parent
eb8a4745
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
298 additions
and
234 deletions
+298
-234
AndroidManifest.xml
...id_android_views/android/app/src/main/AndroidManifest.xml
+2
-5
android_platform_view.dart
...tests/hybrid_android_views/lib/android_platform_view.dart
+19
-5
nested_view_event_page.dart
...ests/hybrid_android_views/lib/nested_view_event_page.dart
+11
-0
main_test.dart
...ion_tests/hybrid_android_views/test_driver/main_test.dart
+51
-3
platform_view.dart
packages/flutter/lib/src/rendering/platform_view.dart
+41
-43
platform_views.dart
packages/flutter/lib/src/services/platform_views.dart
+81
-64
platform_view.dart
packages/flutter/lib/src/widgets/platform_view.dart
+28
-25
platform_view_test.dart
packages/flutter/test/rendering/platform_view_test.dart
+32
-0
fake_platform_views.dart
packages/flutter/test/services/fake_platform_views.dart
+11
-20
platform_views_test.dart
packages/flutter/test/services/platform_views_test.dart
+22
-32
platform_view_test.dart
packages/flutter/test/widgets/platform_view_test.dart
+0
-37
No files found.
dev/integration_tests/hybrid_android_views/android/app/src/main/AndroidManifest.xml
View file @
61c30eed
...
...
@@ -16,7 +16,8 @@ found in the LICENSE file. -->
android:launchMode=
"singleTop"
android:configChanges=
"orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated=
"true"
android:windowSoftInputMode=
"adjustResize"
>
android:windowSoftInputMode=
"adjustResize"
android:exported=
"true"
>
<meta-data
android:name=
"io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value=
"true"
/>
...
...
@@ -28,9 +29,5 @@ found in the LICENSE file. -->
<meta-data
android:name=
"flutterEmbedding"
android:value=
"2"
/>
<!-- Hybrid composition -->
<meta-data
android:name=
"io.flutter.embedded_views_preview"
android:value=
"true"
/>
</application>
</manifest>
dev/integration_tests/hybrid_android_views/lib/android_platform_view.dart
View file @
61c30eed
...
...
@@ -17,6 +17,7 @@ class AndroidPlatformView extends StatelessWidget {
const
AndroidPlatformView
({
Key
?
key
,
this
.
onPlatformViewCreated
,
this
.
useHybridComposition
=
false
,
required
this
.
viewType
,
})
:
assert
(
viewType
!=
null
),
super
(
key:
key
);
...
...
@@ -31,6 +32,9 @@ class AndroidPlatformView extends StatelessWidget {
/// May be null.
final
PlatformViewCreatedCallback
?
onPlatformViewCreated
;
// Use hybrid composition.
final
bool
useHybridComposition
;
@override
Widget
build
(
BuildContext
context
)
{
return
PlatformViewLink
(
...
...
@@ -44,17 +48,27 @@ class AndroidPlatformView extends StatelessWidget {
);
},
onCreatePlatformView:
(
PlatformViewCreationParams
params
)
{
final
AndroidViewController
controller
=
PlatformViewsService
.
initSurfaceAndroidView
(
print
(
'useHybridComposition=
$useHybridComposition
'
);
late
AndroidViewController
controller
;
if
(
useHybridComposition
)
{
controller
=
PlatformViewsService
.
initExpensiveAndroidView
(
id:
params
.
id
,
viewType:
params
.
viewType
,
layoutDirection:
TextDirection
.
ltr
,
)
..
addOnPlatformViewCreatedListener
(
params
.
onPlatformViewCreated
);
);
}
else
{
controller
=
PlatformViewsService
.
initSurfaceAndroidView
(
id:
params
.
id
,
viewType:
params
.
viewType
,
layoutDirection:
TextDirection
.
ltr
,
);
}
if
(
onPlatformViewCreated
!=
null
)
{
controller
.
addOnPlatformViewCreatedListener
(
onPlatformViewCreated
!);
}
return
controller
..
create
();
return
controller
..
addOnPlatformViewCreatedListener
(
params
.
onPlatformViewCreated
)
..
create
();
},
);
}
...
...
dev/integration_tests/hybrid_android_views/lib/nested_view_event_page.dart
View file @
61c30eed
...
...
@@ -39,6 +39,7 @@ class NestedViewEventBodyState extends State<NestedViewEventBody> {
int
?
id
;
int
nestedViewClickCount
=
0
;
bool
showPlatformView
=
true
;
bool
useHybridComposition
=
false
;
@override
Widget
build
(
BuildContext
context
)
{
...
...
@@ -55,6 +56,7 @@ class NestedViewEventBodyState extends State<NestedViewEventBody> {
key:
const
ValueKey
<
String
>(
'PlatformView'
),
viewType:
'simple_view'
,
onPlatformViewCreated:
onPlatformViewCreated
,
useHybridComposition:
useHybridComposition
,
)
:
null
,
),
if
(
_lastTestStatus
!=
_LastTestStatus
.
pending
)
_statusWidget
(),
...
...
@@ -69,6 +71,15 @@ class NestedViewEventBodyState extends State<NestedViewEventBody> {
onPressed:
onTogglePlatformView
,
child:
const
Text
(
'TOGGLE PLATFORM VIEW'
),
),
ElevatedButton
(
key:
const
ValueKey
<
String
>(
'ToggleHybridComposition'
),
child:
const
Text
(
'TOGGLE HYBRID COMPOSITION'
),
onPressed:
()
{
setState
(()
{
useHybridComposition
=
!
useHybridComposition
;
});
},
),
Row
(
children:
<
Widget
>[
ElevatedButton
(
...
...
dev/integration_tests/hybrid_android_views/test_driver/main_test.dart
View file @
61c30eed
...
...
@@ -59,10 +59,58 @@ Future<void> main() async {
},
timeout:
Timeout
.
none
);
});
group
(
'Flutter surface
switch
'
,
()
{
group
(
'Flutter surface
without hybrid composition
'
,
()
{
setUpAll
(()
async
{
final
SerializableFinder
wmListTile
=
find
.
byValueKey
(
'NestedViewEventTile'
);
await
driver
.
tap
(
wmListTile
);
await
driver
.
tap
(
find
.
byValueKey
(
'NestedViewEventTile'
));
});
tearDownAll
(()
async
{
await
driver
.
waitFor
(
find
.
pageBack
());
await
driver
.
tap
(
find
.
pageBack
());
});
test
(
'Uses FlutterSurfaceView when Android view is on the screen'
,
()
async
{
await
driver
.
waitFor
(
find
.
byValueKey
(
'PlatformView'
));
expect
(
await
driver
.
requestData
(
'hierarchy'
),
'|-FlutterView
\n
'
' |-FlutterSurfaceView
\n
'
// Flutter UI
' |-ViewGroup
\n
'
// Platform View
' |-ViewGroup
\n
'
);
// Hide platform view.
final
SerializableFinder
togglePlatformView
=
find
.
byValueKey
(
'TogglePlatformView'
);
await
driver
.
tap
(
togglePlatformView
);
await
driver
.
waitForAbsent
(
find
.
byValueKey
(
'PlatformView'
));
expect
(
await
driver
.
requestData
(
'hierarchy'
),
'|-FlutterView
\n
'
' |-FlutterSurfaceView
\n
'
// Just the Flutter UI
);
// Show platform view again.
await
driver
.
tap
(
togglePlatformView
);
await
driver
.
waitFor
(
find
.
byValueKey
(
'PlatformView'
));
expect
(
await
driver
.
requestData
(
'hierarchy'
),
'|-FlutterView
\n
'
' |-FlutterSurfaceView
\n
'
// Flutter UI
' |-ViewGroup
\n
'
// Platform View
' |-ViewGroup
\n
'
);
},
timeout:
Timeout
.
none
);
});
group
(
'Flutter surface with hybrid composition'
,
()
{
setUpAll
(()
async
{
await
driver
.
tap
(
find
.
byValueKey
(
'NestedViewEventTile'
));
await
driver
.
tap
(
find
.
byValueKey
(
'ToggleHybridComposition'
));
await
driver
.
tap
(
find
.
byValueKey
(
'TogglePlatformView'
));
await
driver
.
tap
(
find
.
byValueKey
(
'TogglePlatformView'
));
});
tearDownAll
(()
async
{
...
...
packages/flutter/lib/src/rendering/platform_view.dart
View file @
61c30eed
...
...
@@ -52,7 +52,7 @@ Set<Type> _factoriesTypeSet<T>(Set<Factory<T>> factories) {
/// A render object for an Android view.
///
/// Requires Android API level 2
0
or greater.
/// Requires Android API level 2
3
or greater.
///
/// [RenderAndroidView] is responsible for sizing, displaying and passing touch events to an
/// Android [View](https://developer.android.com/reference/android/view/View).
...
...
@@ -74,7 +74,7 @@ Set<Type> _factoriesTypeSet<T>(Set<Factory<T>> factories) {
///
/// * [AndroidView] which is a widget that is used to show an Android view.
/// * [PlatformViewsService] which is a service for controlling platform views.
class
RenderAndroidView
extends
RenderBox
with
_PlatformViewGestureMixin
{
class
RenderAndroidView
extends
PlatformViewRenderBox
{
/// Creates a render object for an Android view.
RenderAndroidView
({
required
AndroidViewController
viewController
,
...
...
@@ -86,7 +86,8 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
assert
(
gestureRecognizers
!=
null
),
assert
(
clipBehavior
!=
null
),
_viewController
=
viewController
,
_clipBehavior
=
clipBehavior
{
_clipBehavior
=
clipBehavior
,
super
(
controller:
viewController
,
hitTestBehavior:
hitTestBehavior
,
gestureRecognizers:
gestureRecognizers
)
{
_viewController
.
pointTransformer
=
(
Offset
offset
)
=>
globalToLocal
(
offset
);
updateGestureRecognizers
(
gestureRecognizers
);
_viewController
.
addOnPlatformViewCreatedListener
(
_onPlatformViewCreated
);
...
...
@@ -101,18 +102,22 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
bool
_isDisposed
=
false
;
/// The Android view controller for the Android view associated with this render object.
AndroidViewController
get
viewController
=>
_viewController
;
@override
AndroidViewController
get
controller
=>
_viewController
;
AndroidViewController
_viewController
;
/// Sets a new Android view controller.
///
/// `viewController` must not be null.
set
viewController
(
AndroidViewController
viewController
)
{
@override
set
controller
(
AndroidViewController
controller
)
{
assert
(
_viewController
!=
null
);
assert
(
viewC
ontroller
!=
null
);
if
(
_viewController
==
viewC
ontroller
)
assert
(
c
ontroller
!=
null
);
if
(
_viewController
==
c
ontroller
)
return
;
_viewController
.
removeOnPlatformViewCreatedListener
(
_onPlatformViewCreated
);
_viewController
=
viewController
;
super
.
controller
=
controller
;
_viewController
=
controller
;
_viewController
.
pointTransformer
=
(
Offset
offset
)
=>
globalToLocal
(
offset
);
_sizePlatformView
();
if
(
_viewController
.
isCreated
)
{
markNeedsSemanticsUpdate
();
...
...
@@ -138,26 +143,6 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
markNeedsSemanticsUpdate
();
}
/// {@template flutter.rendering.RenderAndroidView.updateGestureRecognizers}
/// Updates which gestures should be forwarded to the platform view.
///
/// Gesture recognizers created by factories in this set participate in the gesture arena for each
/// pointer that was put down on the render box. If any of the recognizers on this list wins the
/// gesture arena, the entire pointer event sequence starting from the pointer down event
/// will be dispatched to the Android view.
///
/// The `gestureRecognizers` property must not contain more than one factory with the same [Factory.type].
///
/// Setting a new set of gesture recognizer factories with the same [Factory.type]s as the current
/// set has no effect, because the factories' constructors would have already been called with the previous set.
/// {@endtemplate}
///
/// Any active gesture arena the Android view participates in is rejected when the
/// set of gesture recognizers is changed.
void
updateGestureRecognizers
(
Set
<
Factory
<
OneSequenceGestureRecognizer
>>
gestureRecognizers
)
{
_updateGestureRecognizersWithCallBack
(
gestureRecognizers
,
_viewController
.
dispatchPointerEvent
);
}
@override
bool
get
sizedByParent
=>
true
;
...
...
@@ -182,9 +167,8 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
// Android virtual displays cannot have a zero size.
// Trying to size it to 0 crashes the app, which was happening when starting the app
// with a locked screen (see: https://github.com/flutter/flutter/issues/20456).
if
(
_state
==
_PlatformViewState
.
resizing
||
size
.
isEmpty
)
{
if
(
_state
==
_PlatformViewState
.
resizing
||
size
.
isEmpty
)
return
;
}
_state
=
_PlatformViewState
.
resizing
;
markNeedsPaint
();
...
...
@@ -212,7 +196,8 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
void
_setOffset
()
{
SchedulerBinding
.
instance
.
addPostFrameCallback
((
_
)
async
{
if
(!
_isDisposed
)
{
await
_viewController
.
setOffset
(
localToGlobal
(
Offset
.
zero
));
if
(
attached
)
await
_viewController
.
setOffset
(
localToGlobal
(
Offset
.
zero
));
// Schedule a new post frame callback.
_setOffset
();
}
...
...
@@ -221,7 +206,7 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
_viewController
.
textureId
==
null
)
if
(
_viewController
.
textureId
==
null
||
_currentTextureSize
==
null
)
return
;
// As resizing the Android view happens asynchronously we don't know exactly when is a
...
...
@@ -264,14 +249,15 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
context
.
addLayer
(
TextureLayer
(
rect:
offset
&
_currentTextureSize
!,
textureId:
viewController
.
textureId
!,
textureId:
_
viewController
.
textureId
!,
));
}
@override
void
describeSemanticsConfiguration
(
SemanticsConfiguration
config
)
{
super
.
describeSemanticsConfiguration
(
config
);
void
describeSemanticsConfiguration
(
SemanticsConfiguration
config
)
{
// Don't call the super implementation since `platformViewId` should
// be set only when the platform view is created, but the concept of
// a "created" platform view belongs to this subclass.
config
.
isSemanticBoundary
=
true
;
if
(
_viewController
.
isCreated
)
{
...
...
@@ -339,7 +325,7 @@ class RenderUiKitView extends RenderBox {
// any newly arriving events there's nothing we need to invalidate.
PlatformViewHitTestBehavior
hitTestBehavior
;
/// {@macro flutter.rendering.
RenderAndroidView
.updateGestureRecognizers}
/// {@macro flutter.rendering.
PlatformViewRenderBox
.updateGestureRecognizers}
void
updateGestureRecognizers
(
Set
<
Factory
<
OneSequenceGestureRecognizer
>>
gestureRecognizers
)
{
assert
(
gestureRecognizers
!=
null
);
assert
(
...
...
@@ -653,11 +639,11 @@ class PlatformViewRenderBox extends RenderBox with _PlatformViewGestureMixin {
PlatformViewController
get
controller
=>
_controller
;
PlatformViewController
_controller
;
/// This value must not be null, and setting it to a new value will result in a repaint.
set
controller
(
PlatformViewController
controller
)
{
set
controller
(
covariant
PlatformViewController
controller
)
{
assert
(
controller
!=
null
);
assert
(
controller
.
viewId
!=
null
&&
controller
.
viewId
>
-
1
);
if
(
_controller
==
controller
)
{
if
(
_controller
==
controller
)
{
return
;
}
final
bool
needsSemanticsUpdate
=
_controller
.
viewId
!=
controller
.
viewId
;
...
...
@@ -668,7 +654,19 @@ class PlatformViewRenderBox extends RenderBox with _PlatformViewGestureMixin {
}
}
/// {@macro flutter.rendering.RenderAndroidView.updateGestureRecognizers}
/// {@template flutter.rendering.PlatformViewRenderBox.updateGestureRecognizers}
/// Updates which gestures should be forwarded to the platform view.
///
/// Gesture recognizers created by factories in this set participate in the gesture arena for each
/// pointer that was put down on the render box. If any of the recognizers on this list wins the
/// gesture arena, the entire pointer event sequence starting from the pointer down event
/// will be dispatched to the Android view.
///
/// The `gestureRecognizers` property must not contain more than one factory with the same [Factory.type].
///
/// Setting a new set of gesture recognizer factories with the same [Factory.type]s as the current
/// set has no effect, because the factories' constructors would have already been called with the previous set.
/// {@endtemplate}
///
/// Any active gesture arena the `PlatformView` participates in is rejected when the
/// set of gesture recognizers is changed.
...
...
@@ -700,7 +698,7 @@ class PlatformViewRenderBox extends RenderBox with _PlatformViewGestureMixin {
}
@override
void
describeSemanticsConfiguration
(
SemanticsConfiguration
config
)
{
void
describeSemanticsConfiguration
(
SemanticsConfiguration
config
)
{
super
.
describeSemanticsConfiguration
(
config
);
assert
(
_controller
.
viewId
!=
null
);
config
.
isSemanticBoundary
=
true
;
...
...
packages/flutter/lib/src/services/platform_views.dart
View file @
61c30eed
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/platform_view.dart
View file @
61c30eed
...
...
@@ -15,7 +15,7 @@ import 'framework.dart';
/// Embeds an Android view in the Widget hierarchy.
///
/// Requires Android API level 2
0
or greater.
/// Requires Android API level 2
3
or greater.
///
/// Embedding Android views is an expensive operation and should be avoided when a Flutter
/// equivalent is possible.
...
...
@@ -681,7 +681,7 @@ class _AndroidPlatformView extends LeafRenderObjectWidget {
@override
void
updateRenderObject
(
BuildContext
context
,
RenderAndroidView
renderObject
)
{
renderObject
.
viewC
ontroller
=
controller
;
renderObject
.
c
ontroller
=
controller
;
renderObject
.
hitTestBehavior
=
hitTestBehavior
;
renderObject
.
updateGestureRecognizers
(
gestureRecognizers
);
renderObject
.
clipBehavior
=
clipBehavior
;
...
...
@@ -842,15 +842,11 @@ class PlatformViewLink extends StatefulWidget {
class
_PlatformViewLinkState
extends
State
<
PlatformViewLink
>
{
int
?
_id
;
PlatformViewController
?
_controller
;
bool
_platformViewCreated
=
false
;
Widget
?
_surface
;
FocusNode
?
_focusNode
;
@override
Widget
build
(
BuildContext
context
)
{
if
(!
_platformViewCreated
)
{
return
const
SizedBox
.
expand
();
}
_surface
??=
widget
.
_surfaceFactory
(
context
,
_controller
!);
return
Focus
(
focusNode:
_focusNode
,
...
...
@@ -875,9 +871,6 @@ class _PlatformViewLinkState extends State<PlatformViewLink> {
// The _surface has to be recreated as its controller is disposed.
// Setting _surface to null will trigger its creation in build().
_surface
=
null
;
// We are about to create a new platform view.
_platformViewCreated
=
false
;
_initialize
();
}
}
...
...
@@ -888,16 +881,12 @@ class _PlatformViewLinkState extends State<PlatformViewLink> {
PlatformViewCreationParams
.
_
(
id:
_id
!,
viewType:
widget
.
viewType
,
onPlatformViewCreated:
_onPlatformViewCreated
,
onPlatformViewCreated:
(
_
)
{}
,
onFocusChanged:
_handlePlatformFocusChanged
,
),
);
}
void
_onPlatformViewCreated
(
int
id
)
{
setState
(()
{
_platformViewCreated
=
true
;
});
}
void
_handleFrameworkFocusChanged
(
bool
isFocused
)
{
if
(!
isFocused
)
{
_controller
?.
clearFocus
();
...
...
@@ -1020,18 +1009,18 @@ class PlatformViewSurface extends LeafRenderObjectWidget {
/// Integrates an Android view with Flutter's compositor, touch, and semantics subsystems.
///
/// The compositor integration is done by adding a [PlatformViewLayer] to the layer tree. [PlatformViewLayer]
/// isn't supported on all platforms. Custom Flutter embedders can support
/// [PlatformViewLayer]s by implementing a SystemCompositor.
/// The compositor integration is done by adding a [TextureLayer] to the layer tree.
///
/// The widget fills all available space, the parent of this object must provide bounded layout
/// constraints.
/// The parent of this object must provide bounded layout constraints.
///
/// If the associated platform view is not created, the [AndroidViewSurface] does not paint any contents.
///
/// When possible, you may want to use [AndroidView] directly, since it requires less boilerplate code
/// than [AndroidViewSurface], and there's no difference in performance, or other trade-off(s).
///
/// See also:
///
/// * [AndroidView] which embeds an Android platform view in the widget hierarchy
using a [TextureLayer]
.
/// * [AndroidView] which embeds an Android platform view in the widget hierarchy.
/// * [UiKitView] which embeds an iOS platform view in the widget hierarchy.
class
AndroidViewSurface
extends
PlatformViewSurface
{
/// Construct an `AndroidPlatformViewSurface`.
...
...
@@ -1052,12 +1041,26 @@ class AndroidViewSurface extends PlatformViewSurface {
@override
RenderObject
createRenderObject
(
BuildContext
context
)
{
final
PlatformViewRenderBox
renderBox
=
super
.
createRenderObject
(
context
)
as
PlatformViewRenderBox
;
(
controller
as
AndroidViewController
).
pointTransformer
=
final
AndroidViewController
viewController
=
controller
as
AndroidViewController
;
// Compose using the Android view hierarchy.
// This is useful when embedding a SurfaceView into a Flutter app.
// SurfaceViews cannot be composed using GL textures.
if
(
viewController
is
ExpensiveAndroidViewController
)
{
final
PlatformViewRenderBox
renderBox
=
super
.
createRenderObject
(
context
)
as
PlatformViewRenderBox
;
viewController
.
pointTransformer
=
(
Offset
position
)
=>
renderBox
.
globalToLocal
(
position
);
return
renderBox
;
}
// Use GL texture based composition.
// App should use GL texture unless they require to embed a SurfaceView.
final
RenderAndroidView
renderBox
=
RenderAndroidView
(
viewController:
viewController
,
gestureRecognizers:
gestureRecognizers
,
hitTestBehavior:
hitTestBehavior
,
);
viewController
.
pointTransformer
=
(
Offset
position
)
=>
renderBox
.
globalToLocal
(
position
);
return
renderBox
;
}
}
packages/flutter/test/rendering/platform_view_test.dart
View file @
61c30eed
...
...
@@ -151,6 +151,38 @@ void main() {
// Passes if no crashes.
});
test
(
'created callback is reset when controller is changed'
,
()
{
final
FakeAndroidPlatformViewsController
viewsController
=
FakeAndroidPlatformViewsController
();
viewsController
.
registerViewType
(
'webview'
);
final
AndroidViewController
firstController
=
PlatformViewsService
.
initAndroidView
(
id:
0
,
viewType:
'webview'
,
layoutDirection:
TextDirection
.
rtl
,
);
final
RenderAndroidView
renderBox
=
RenderAndroidView
(
viewController:
firstController
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
gestureRecognizers:
<
Factory
<
OneSequenceGestureRecognizer
>>{},
);
layout
(
renderBox
);
pumpFrame
(
phase:
EnginePhase
.
flushSemantics
);
expect
(
firstController
.
createdCallbacks
,
isNotEmpty
);
expect
(
firstController
.
createdCallbacks
.
length
,
1
);
final
AndroidViewController
secondController
=
PlatformViewsService
.
initAndroidView
(
id:
0
,
viewType:
'webview'
,
layoutDirection:
TextDirection
.
rtl
,
);
// Reset controller.
renderBox
.
controller
=
secondController
;
expect
(
firstController
.
createdCallbacks
,
isEmpty
);
expect
(
secondController
.
createdCallbacks
,
isNotEmpty
);
expect
(
secondController
.
createdCallbacks
.
length
,
1
);
});
test
(
'render object changed its visual appearance after texture is created'
,
()
{
FakeAsync
().
run
((
FakeAsync
async
)
{
final
AndroidViewController
viewController
=
...
...
packages/flutter/test/services/fake_platform_views.dart
View file @
61c30eed
...
...
@@ -84,23 +84,22 @@ class FakeAndroidViewController implements AndroidViewController {
@override
Future
<
Size
>
setSize
(
Size
size
)
{
throw
UnimplementedError
(
);
return
Future
<
Size
>.
value
(
size
);
}
@override
Future
<
void
>
setOffset
(
Offset
off
)
{
throw
UnimplementedError
();
}
Future
<
void
>
setOffset
(
Offset
off
)
async
{}
@override
int
get
textureId
=>
throw
UnimplementedError
()
;
int
get
textureId
=>
0
;
@override
bool
get
isCreated
=>
throw
UnimplementedError
()
;
bool
get
isCreated
=>
created
;
@override
void
addOnPlatformViewCreatedListener
(
PlatformViewCreatedCallback
listener
)
=>
throw
UnimplementedError
();
void
addOnPlatformViewCreatedListener
(
PlatformViewCreatedCallback
listener
)
{
created
=
true
;
}
@override
void
removeOnPlatformViewCreatedListener
(
PlatformViewCreatedCallback
listener
)
{
...
...
@@ -118,9 +117,10 @@ class FakeAndroidViewController implements AndroidViewController {
}
@override
Future
<
void
>
create
()
async
{
created
=
true
;
}
Future
<
void
>
create
()
async
{}
@override
List
<
PlatformViewCreatedCallback
>
get
createdCallbacks
=>
<
PlatformViewCreatedCallback
>[];
}
class
FakeAndroidPlatformViewsController
{
...
...
@@ -143,8 +143,6 @@ class FakeAndroidPlatformViewsController {
int
?
lastClearedFocusViewId
;
bool
synchronizeToNativeViewHierarchy
=
true
;
Map
<
int
,
Offset
>
offsets
=
<
int
,
Offset
>{};
void
registerViewType
(
String
viewType
)
{
...
...
@@ -174,8 +172,6 @@ class FakeAndroidPlatformViewsController {
return
_clearFocus
(
call
);
case
'offset'
:
return
_offset
(
call
);
case
'synchronizeToNativeViewHierarchy'
:
return
_synchronizeToNativeViewHierarchy
(
call
);
}
return
Future
<
dynamic
>.
sync
(()
=>
null
);
}
...
...
@@ -318,11 +314,6 @@ class FakeAndroidPlatformViewsController {
lastClearedFocusViewId
=
id
;
return
Future
<
dynamic
>.
sync
(()
=>
null
);
}
Future
<
dynamic
>
_synchronizeToNativeViewHierarchy
(
MethodCall
call
)
{
synchronizeToNativeViewHierarchy
=
call
.
arguments
as
bool
;
return
Future
<
dynamic
>.
sync
(()
=>
null
);
}
}
class
FakeIosPlatformViewsController
{
...
...
packages/flutter/test/services/platform_views_test.dart
View file @
61c30eed
...
...
@@ -18,7 +18,7 @@ void main() {
});
test
(
'create Android view of unregistered type'
,
()
async
{
expect
(
expect
Later
(
()
{
return
PlatformViewsService
.
initAndroidView
(
id:
0
,
...
...
@@ -29,16 +29,25 @@ void main() {
throwsA
(
isA
<
PlatformException
>()),
);
expect
(
()
{
return
PlatformViewsService
.
initSurfaceAndroidView
(
id:
0
,
viewType:
'web'
,
layoutDirection:
TextDirection
.
ltr
,
).
create
();
},
throwsA
(
isA
<
PlatformException
>()),
);
try
{
await
PlatformViewsService
.
initSurfaceAndroidView
(
id:
0
,
viewType:
'web'
,
layoutDirection:
TextDirection
.
ltr
,
).
create
();
}
catch
(
e
)
{
expect
(
false
,
isTrue
,
reason:
'did not expected any exception, but instead got `
$e
`'
);
}
try
{
await
PlatformViewsService
.
initAndroidView
(
id:
0
,
viewType:
'web'
,
layoutDirection:
TextDirection
.
ltr
,
).
create
();
}
catch
(
e
)
{
expect
(
false
,
isTrue
,
reason:
'did not expected any exception, but instead got `
$e
`'
);
}
});
test
(
'create Android views'
,
()
async
{
...
...
@@ -47,13 +56,13 @@ void main() {
.
setSize
(
const
Size
(
100.0
,
100.0
));
await
PlatformViewsService
.
initAndroidView
(
id:
1
,
viewType:
'webview'
,
layoutDirection:
TextDirection
.
rtl
)
.
setSize
(
const
Size
(
200.0
,
300.0
));
// This platform view isn't created until the size is set.
await
PlatformViewsService
.
initSurfaceAndroidView
(
id:
2
,
viewType:
'webview'
,
layoutDirection:
TextDirection
.
rtl
).
create
();
expect
(
viewsController
.
views
,
unorderedEquals
(<
FakeAndroidPlatformView
>[
const
FakeAndroidPlatformView
(
0
,
'webview'
,
Size
(
100.0
,
100.0
),
AndroidViewController
.
kAndroidLayoutDirectionLtr
,
null
),
const
FakeAndroidPlatformView
(
1
,
'webview'
,
Size
(
200.0
,
300.0
),
AndroidViewController
.
kAndroidLayoutDirectionRtl
,
null
),
const
FakeAndroidPlatformView
(
2
,
'webview'
,
null
,
AndroidViewController
.
kAndroidLayoutDirectionRtl
,
true
),
]),
);
});
...
...
@@ -65,7 +74,7 @@ void main() {
viewType:
'webview'
,
layoutDirection:
TextDirection
.
ltr
,
).
setSize
(
const
Size
(
100.0
,
100.0
));
expect
(
expect
Later
(
()
=>
PlatformViewsService
.
initAndroidView
(
id:
0
,
viewType:
'web'
,
...
...
@@ -73,20 +82,6 @@ void main() {
).
setSize
(
const
Size
(
100.0
,
100.0
)),
throwsA
(
isA
<
PlatformException
>()),
);
await
PlatformViewsService
.
initSurfaceAndroidView
(
id:
1
,
viewType:
'webview'
,
layoutDirection:
TextDirection
.
ltr
,
).
create
();
expect
(
()
=>
PlatformViewsService
.
initSurfaceAndroidView
(
id:
1
,
viewType:
'web'
,
layoutDirection:
TextDirection
.
ltr
,
).
create
(),
throwsA
(
isA
<
PlatformException
>()),
);
});
test
(
'dispose Android view'
,
()
async
{
...
...
@@ -240,11 +235,6 @@ void main() {
await
viewController
.
setOffset
(
const
Offset
(
10
,
20
));
expect
(
viewsController
.
offsets
,
equals
(<
int
,
Offset
>{}));
});
test
(
'synchronizeToNativeViewHierarchy'
,
()
async
{
await
PlatformViewsService
.
synchronizeToNativeViewHierarchy
(
false
);
expect
(
viewsController
.
synchronizeToNativeViewHierarchy
,
false
);
});
});
group
(
'iOS'
,
()
{
...
...
packages/flutter/test/widgets/platform_view_test.dart
View file @
61c30eed
...
...
@@ -2312,43 +2312,6 @@ void main() {
expect
(
factoryInvocationCount
,
1
);
});
testWidgets
(
'PlatformViewLink Widget init, should create a SizedBox widget before onPlatformViewCreated and a PlatformViewSurface after'
,
(
WidgetTester
tester
)
async
{
final
int
currentViewId
=
platformViewsRegistry
.
getNextPlatformViewId
();
late
int
createdPlatformViewId
;
late
PlatformViewCreatedCallback
onPlatformViewCreatedCallBack
;
final
PlatformViewLink
platformViewLink
=
PlatformViewLink
(
viewType:
'webview'
,
onCreatePlatformView:
(
PlatformViewCreationParams
params
)
{
onPlatformViewCreatedCallBack
=
params
.
onPlatformViewCreated
;
createdPlatformViewId
=
params
.
id
;
return
FakePlatformViewController
(
params
.
id
);
},
surfaceFactory:
(
BuildContext
context
,
PlatformViewController
controller
)
{
return
PlatformViewSurface
(
gestureRecognizers:
const
<
Factory
<
OneSequenceGestureRecognizer
>>{},
controller:
controller
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
);
},
);
await
tester
.
pumpWidget
(
platformViewLink
);
expect
(()
=>
tester
.
allWidgets
.
whereType
<
SizedBox
>().
first
,
returnsNormally
);
onPlatformViewCreatedCallBack
(
createdPlatformViewId
);
await
tester
.
pump
();
expect
(()
=>
tester
.
allWidgets
.
whereType
<
PlatformViewSurface
>().
first
,
returnsNormally
);
expect
(
createdPlatformViewId
,
currentViewId
+
1
);
},
);
testWidgets
(
'PlatformViewLink Widget dispose'
,
(
WidgetTester
tester
)
async
{
late
FakePlatformViewController
disposedController
;
final
PlatformViewLink
platformViewLink
=
PlatformViewLink
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment