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
333c9618
Unverified
Commit
333c9618
authored
Aug 06, 2019
by
Chris Yang
Committed by
GitHub
Aug 06, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Extract common PlatformView functionality: Gesture and PointerEvent (#37497)
parent
0cd0c660
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
434 additions
and
71 deletions
+434
-71
platform_view.dart
packages/flutter/lib/src/rendering/platform_view.dart
+102
-66
platform_views.dart
packages/flutter/lib/src/services/platform_views.dart
+4
-0
platform_view.dart
packages/flutter/lib/src/widgets/platform_view.dart
+53
-3
platform_view_test.dart
packages/flutter/test/rendering/platform_view_test.dart
+12
-1
fake_platform_views.dart
packages/flutter/test/services/fake_platform_views.dart
+13
-0
platform_view_test.dart
packages/flutter/test/widgets/platform_view_test.dart
+250
-1
No files found.
packages/flutter/lib/src/rendering/platform_view.dart
View file @
333c9618
...
@@ -75,12 +75,12 @@ Set<Type> _factoriesTypeSet<T>(Set<Factory<T>> factories) {
...
@@ -75,12 +75,12 @@ Set<Type> _factoriesTypeSet<T>(Set<Factory<T>> factories) {
///
///
/// * [AndroidView] which is a widget that is used to show an Android view.
/// * [AndroidView] which is a widget that is used to show an Android view.
/// * [PlatformViewsService] which is a service for controlling platform views.
/// * [PlatformViewsService] which is a service for controlling platform views.
class
RenderAndroidView
extends
RenderBox
{
class
RenderAndroidView
extends
RenderBox
with
_PlatformViewGestureMixin
{
/// Creates a render object for an Android view.
/// Creates a render object for an Android view.
RenderAndroidView
({
RenderAndroidView
({
@required
AndroidViewController
viewController
,
@required
AndroidViewController
viewController
,
@required
this
.
hitTestBehavior
,
@required
PlatformViewHitTestBehavior
hitTestBehavior
,
@required
Set
<
Factory
<
OneSequenceGestureRecognizer
>>
gestureRecognizers
,
@required
Set
<
Factory
<
OneSequenceGestureRecognizer
>>
gestureRecognizers
,
})
:
assert
(
viewController
!=
null
),
})
:
assert
(
viewController
!=
null
),
assert
(
hitTestBehavior
!=
null
),
assert
(
hitTestBehavior
!=
null
),
...
@@ -89,6 +89,7 @@ class RenderAndroidView extends RenderBox {
...
@@ -89,6 +89,7 @@ class RenderAndroidView extends RenderBox {
_motionEventsDispatcher
=
_MotionEventsDispatcher
(
globalToLocal
,
viewController
);
_motionEventsDispatcher
=
_MotionEventsDispatcher
(
globalToLocal
,
viewController
);
updateGestureRecognizers
(
gestureRecognizers
);
updateGestureRecognizers
(
gestureRecognizers
);
_viewController
.
addOnPlatformViewCreatedListener
(
_onPlatformViewCreated
);
_viewController
.
addOnPlatformViewCreatedListener
(
_onPlatformViewCreated
);
this
.
hitTestBehavior
=
hitTestBehavior
;
}
}
_PlatformViewState
_state
=
_PlatformViewState
.
uninitialized
;
_PlatformViewState
_state
=
_PlatformViewState
.
uninitialized
;
...
@@ -117,11 +118,6 @@ class RenderAndroidView extends RenderBox {
...
@@ -117,11 +118,6 @@ class RenderAndroidView extends RenderBox {
markNeedsSemanticsUpdate
();
markNeedsSemanticsUpdate
();
}
}
/// How to behave during hit testing.
// The implicit setter is enough here as changing this value will just affect
// any newly arriving events there's nothing we need to invalidate.
PlatformViewHitTestBehavior
hitTestBehavior
;
/// {@template flutter.rendering.platformView.updateGestureRecognizers}
/// {@template flutter.rendering.platformView.updateGestureRecognizers}
/// Updates which gestures should be forwarded to the platform view.
/// Updates which gestures should be forwarded to the platform view.
///
///
...
@@ -139,16 +135,7 @@ class RenderAndroidView extends RenderBox {
...
@@ -139,16 +135,7 @@ class RenderAndroidView extends RenderBox {
/// Any active gesture arena the Android view participates in is rejected when the
/// Any active gesture arena the Android view participates in is rejected when the
/// set of gesture recognizers is changed.
/// set of gesture recognizers is changed.
void
updateGestureRecognizers
(
Set
<
Factory
<
OneSequenceGestureRecognizer
>>
gestureRecognizers
)
{
void
updateGestureRecognizers
(
Set
<
Factory
<
OneSequenceGestureRecognizer
>>
gestureRecognizers
)
{
assert
(
gestureRecognizers
!=
null
);
_updateGestureRecognizersWithCallBack
(
gestureRecognizers
,
_motionEventsDispatcher
.
handlePointerEvent
);
assert
(
_factoriesTypeSet
(
gestureRecognizers
).
length
==
gestureRecognizers
.
length
,
'There were multiple gesture recognizer factories for the same type, there must only be a single '
'gesture recognizer factory for each gesture recognizer type.'
,);
if
(
_factoryTypesSetEquals
(
gestureRecognizers
,
_gestureRecognizer
?.
gestureRecognizerFactories
))
{
return
;
}
_gestureRecognizer
?.
dispose
();
_gestureRecognizer
=
_AndroidViewGestureRecognizer
(
_motionEventsDispatcher
,
gestureRecognizers
);
}
}
@override
@override
...
@@ -162,8 +149,6 @@ class RenderAndroidView extends RenderBox {
...
@@ -162,8 +149,6 @@ class RenderAndroidView extends RenderBox {
_MotionEventsDispatcher
_motionEventsDispatcher
;
_MotionEventsDispatcher
_motionEventsDispatcher
;
_AndroidViewGestureRecognizer
_gestureRecognizer
;
@override
@override
void
performResize
()
{
void
performResize
()
{
size
=
constraints
.
biggest
;
size
=
constraints
.
biggest
;
...
@@ -229,24 +214,6 @@ class RenderAndroidView extends RenderBox {
...
@@ -229,24 +214,6 @@ class RenderAndroidView extends RenderBox {
));
));
}
}
@override
bool
hitTest
(
BoxHitTestResult
result
,
{
Offset
position
})
{
if
(
hitTestBehavior
==
PlatformViewHitTestBehavior
.
transparent
||
!
size
.
contains
(
position
))
return
false
;
result
.
add
(
BoxHitTestEntry
(
this
,
position
));
return
hitTestBehavior
==
PlatformViewHitTestBehavior
.
opaque
;
}
@override
bool
hitTestSelf
(
Offset
position
)
=>
hitTestBehavior
!=
PlatformViewHitTestBehavior
.
transparent
;
@override
void
handleEvent
(
PointerEvent
event
,
HitTestEntry
entry
)
{
if
(
event
is
PointerDownEvent
)
{
_gestureRecognizer
.
addPointer
(
event
);
}
}
@override
@override
void
describeSemanticsConfiguration
(
SemanticsConfiguration
config
)
{
void
describeSemanticsConfiguration
(
SemanticsConfiguration
config
)
{
super
.
describeSemanticsConfiguration
(
config
);
super
.
describeSemanticsConfiguration
(
config
);
...
@@ -257,12 +224,6 @@ class RenderAndroidView extends RenderBox {
...
@@ -257,12 +224,6 @@ class RenderAndroidView extends RenderBox {
config
.
platformViewId
=
_viewController
.
id
;
config
.
platformViewId
=
_viewController
.
id
;
}
}
}
}
@override
void
detach
()
{
_gestureRecognizer
.
reset
();
super
.
detach
();
}
}
}
/// A render object for an iOS UIKit UIView.
/// A render object for an iOS UIKit UIView.
...
@@ -486,15 +447,17 @@ class _UiKitViewGestureRecognizer extends OneSequenceGestureRecognizer {
...
@@ -486,15 +447,17 @@ class _UiKitViewGestureRecognizer extends OneSequenceGestureRecognizer {
}
}
}
}
typedef
_HandlePointerEvent
=
void
Function
(
PointerEvent
event
);
// This recognizer constructs gesture recognizers from a set of gesture recognizer factories
// This recognizer constructs gesture recognizers from a set of gesture recognizer factories
// it was give, adds all of them to a gesture arena team with the _
Android
ViewGestureRecognizer
// it was give, adds all of them to a gesture arena team with the _
Platform
ViewGestureRecognizer
// as the team captain.
// as the team captain.
// As long as t
a gesture arena is unresolved
the recognizer caches all pointer events.
// As long as t
he gesture arena is unresolved,
the recognizer caches all pointer events.
// When the team wins
the recognizer sends all the cached point events to the embedded Android view
, and
// When the team wins
, the recognizer sends all the cached pointer events to `_handlePointerEvent`
, and
// sets itself to a "forwarding mode" where it will forward any new pointer event to
the Android view
.
// sets itself to a "forwarding mode" where it will forward any new pointer event to
`_handlePointerEvent`
.
class
_
Android
ViewGestureRecognizer
extends
OneSequenceGestureRecognizer
{
class
_
Platform
ViewGestureRecognizer
extends
OneSequenceGestureRecognizer
{
_
Android
ViewGestureRecognizer
(
_
Platform
ViewGestureRecognizer
(
this
.
dispatcher
,
_HandlePointerEvent
handlePointerEvent
,
this
.
gestureRecognizerFactories
,
{
this
.
gestureRecognizerFactories
,
{
PointerDeviceKind
kind
,
PointerDeviceKind
kind
,
})
:
super
(
kind:
kind
)
{
})
:
super
(
kind:
kind
)
{
...
@@ -505,18 +468,19 @@ class _AndroidViewGestureRecognizer extends OneSequenceGestureRecognizer {
...
@@ -505,18 +468,19 @@ class _AndroidViewGestureRecognizer extends OneSequenceGestureRecognizer {
return
recognizerFactory
.
constructor
()..
team
=
team
;
return
recognizerFactory
.
constructor
()..
team
=
team
;
},
},
).
toSet
();
).
toSet
();
_handlePointerEvent
=
handlePointerEvent
;
}
}
final
_MotionEventsDispatcher
dispatcher
;
_HandlePointerEvent
_handlePointerEvent
;
// Maps a pointer to a list of its cached pointer events.
// Maps a pointer to a list of its cached pointer events.
// Before the arena for a pointer is resolved all events are cached here, if we win the arena
// Before the arena for a pointer is resolved all events are cached here, if we win the arena
// the cached events are dispatched to
the view
, if we lose the arena we clear the cache for
// the cached events are dispatched to
`_handlePointerEvent`
, if we lose the arena we clear the cache for
// the pointer.
// the pointer.
final
Map
<
int
,
List
<
PointerEvent
>>
cachedEvents
=
<
int
,
List
<
PointerEvent
>>{};
final
Map
<
int
,
List
<
PointerEvent
>>
cachedEvents
=
<
int
,
List
<
PointerEvent
>>{};
// Pointer for which we have already won the arena, events for pointers in this set are
// Pointer for which we have already won the arena, events for pointers in this set are
// immediately dispatched to
the Android view
.
// immediately dispatched to
`_handlePointerEvent`
.
final
Set
<
int
>
forwardedPointers
=
<
int
>{};
final
Set
<
int
>
forwardedPointers
=
<
int
>{};
// We use OneSequenceGestureRecognizers as they support gesture arena teams.
// We use OneSequenceGestureRecognizers as they support gesture arena teams.
...
@@ -534,7 +498,7 @@ class _AndroidViewGestureRecognizer extends OneSequenceGestureRecognizer {
...
@@ -534,7 +498,7 @@ class _AndroidViewGestureRecognizer extends OneSequenceGestureRecognizer {
}
}
@override
@override
String
get
debugDescription
=>
'
Android
view'
;
String
get
debugDescription
=>
'
Platform
view'
;
@override
@override
void
didStopTrackingLastPointer
(
int
pointer
)
{
}
void
didStopTrackingLastPointer
(
int
pointer
)
{
}
...
@@ -542,16 +506,16 @@ class _AndroidViewGestureRecognizer extends OneSequenceGestureRecognizer {
...
@@ -542,16 +506,16 @@ class _AndroidViewGestureRecognizer extends OneSequenceGestureRecognizer {
@override
@override
void
handleEvent
(
PointerEvent
event
)
{
void
handleEvent
(
PointerEvent
event
)
{
if
(!
forwardedPointers
.
contains
(
event
.
pointer
))
{
if
(!
forwardedPointers
.
contains
(
event
.
pointer
))
{
cacheEvent
(
event
);
_
cacheEvent
(
event
);
}
else
{
}
else
{
dispatcher
.
handlePointerEvent
(
event
);
_
handlePointerEvent
(
event
);
}
}
stopTrackingIfPointerNoLongerDown
(
event
);
stopTrackingIfPointerNoLongerDown
(
event
);
}
}
@override
@override
void
acceptGesture
(
int
pointer
)
{
void
acceptGesture
(
int
pointer
)
{
flushPointerCache
(
pointer
);
_
flushPointerCache
(
pointer
);
forwardedPointers
.
add
(
pointer
);
forwardedPointers
.
add
(
pointer
);
}
}
...
@@ -561,15 +525,15 @@ class _AndroidViewGestureRecognizer extends OneSequenceGestureRecognizer {
...
@@ -561,15 +525,15 @@ class _AndroidViewGestureRecognizer extends OneSequenceGestureRecognizer {
cachedEvents
.
remove
(
pointer
);
cachedEvents
.
remove
(
pointer
);
}
}
void
cacheEvent
(
PointerEvent
event
)
{
void
_
cacheEvent
(
PointerEvent
event
)
{
if
(!
cachedEvents
.
containsKey
(
event
.
pointer
))
{
if
(!
cachedEvents
.
containsKey
(
event
.
pointer
))
{
cachedEvents
[
event
.
pointer
]
=
<
PointerEvent
>
[];
cachedEvents
[
event
.
pointer
]
=
<
PointerEvent
>
[];
}
}
cachedEvents
[
event
.
pointer
].
add
(
event
);
cachedEvents
[
event
.
pointer
].
add
(
event
);
}
}
void
flushPointerCache
(
int
pointer
)
{
void
_
flushPointerCache
(
int
pointer
)
{
cachedEvents
.
remove
(
pointer
)?.
forEach
(
dispatcher
.
handlePointerEvent
);
cachedEvents
.
remove
(
pointer
)?.
forEach
(
_
handlePointerEvent
);
}
}
@override
@override
...
@@ -728,18 +692,24 @@ class _MotionEventsDispatcher {
...
@@ -728,18 +692,24 @@ class _MotionEventsDispatcher {
/// A render object for embedding a platform view.
/// A render object for embedding a platform view.
///
///
/// [PlatformViewRenderBox] presents a platform view by adding a [PlatformViewLayer] layer,
integrates it with the gesture arenas system
/// [PlatformViewRenderBox] presents a platform view by adding a [PlatformViewLayer] layer,
/// and adds relevant semantic nodes to the semantics tree.
///
integrates it with the gesture arenas system
and adds relevant semantic nodes to the semantics tree.
class
PlatformViewRenderBox
extends
RenderBox
{
class
PlatformViewRenderBox
extends
RenderBox
with
_PlatformViewGestureMixin
{
/// Creating a render object for a [PlatformViewSurface].
/// Creating a render object for a [PlatformViewSurface].
///
///
/// The `controller` parameter must not be null.
/// The `controller` parameter must not be null.
PlatformViewRenderBox
({
PlatformViewRenderBox
({
@required
PlatformViewController
controller
,
@required
PlatformViewController
controller
,
@required
PlatformViewHitTestBehavior
hitTestBehavior
,
})
:
assert
(
controller
!=
null
&&
controller
.
viewId
!=
null
&&
controller
.
viewId
>
-
1
),
@required
Set
<
Factory
<
OneSequenceGestureRecognizer
>>
gestureRecognizers
,
_controller
=
controller
;
})
:
assert
(
controller
!=
null
&&
controller
.
viewId
!=
null
&&
controller
.
viewId
>
-
1
),
assert
(
hitTestBehavior
!=
null
),
assert
(
gestureRecognizers
!=
null
),
_controller
=
controller
{
this
.
hitTestBehavior
=
hitTestBehavior
;
updateGestureRecognizers
(
gestureRecognizers
);
}
/// Sets the [controller] for this render object.
/// Sets the [controller] for this render object.
///
///
...
@@ -759,6 +729,19 @@ class PlatformViewRenderBox extends RenderBox {
...
@@ -759,6 +729,19 @@ class PlatformViewRenderBox extends RenderBox {
}
}
}
}
/// How to behave during hit testing.
// The implicit setter is enough here as changing this value will just affect
// any newly arriving events there's nothing we need to invalidate.
// PlatformViewHitTestBehavior hitTestBehavior;
/// {@macro flutter.rendering.platformView.updateGestureRecognizers}
///
/// Any active gesture arena the `PlatformView` participates in is rejected when the
/// set of gesture recognizers is changed.
void
updateGestureRecognizers
(
Set
<
Factory
<
OneSequenceGestureRecognizer
>>
gestureRecognizers
)
{
_updateGestureRecognizersWithCallBack
(
gestureRecognizers
,
_controller
.
dispatchPointerEvent
);
}
PlatformViewController
_controller
;
PlatformViewController
_controller
;
@override
@override
...
@@ -791,3 +774,56 @@ class PlatformViewRenderBox extends RenderBox {
...
@@ -791,3 +774,56 @@ class PlatformViewRenderBox extends RenderBox {
config
.
platformViewId
=
_controller
.
viewId
;
config
.
platformViewId
=
_controller
.
viewId
;
}
}
}
}
/// The Mixin handling the pointer events and gestures of a platform view render box.
mixin
_PlatformViewGestureMixin
on
RenderBox
{
/// How to behave during hit testing.
// The implicit setter is enough here as changing this value will just affect
// any newly arriving events there's nothing we need to invalidate.
PlatformViewHitTestBehavior
hitTestBehavior
;
/// {@macro flutter.rendering.platformView.updateGestureRecognizers}
///
/// Any active gesture arena the `PlatformView` participates in is rejected when the
/// set of gesture recognizers is changed.
void
_updateGestureRecognizersWithCallBack
(
Set
<
Factory
<
OneSequenceGestureRecognizer
>>
gestureRecognizers
,
_HandlePointerEvent
_handlePointerEvent
)
{
assert
(
gestureRecognizers
!=
null
);
assert
(
_factoriesTypeSet
(
gestureRecognizers
).
length
==
gestureRecognizers
.
length
,
'There were multiple gesture recognizer factories for the same type, there must only be a single '
'gesture recognizer factory for each gesture recognizer type.'
,);
if
(
_factoryTypesSetEquals
(
gestureRecognizers
,
_gestureRecognizer
?.
gestureRecognizerFactories
))
{
return
;
}
_gestureRecognizer
?.
dispose
();
_gestureRecognizer
=
_PlatformViewGestureRecognizer
(
_handlePointerEvent
,
gestureRecognizers
);
}
_PlatformViewGestureRecognizer
_gestureRecognizer
;
@override
bool
hitTest
(
BoxHitTestResult
result
,
{
Offset
position
})
{
if
(
hitTestBehavior
==
PlatformViewHitTestBehavior
.
transparent
||
!
size
.
contains
(
position
))
{
return
false
;
}
result
.
add
(
BoxHitTestEntry
(
this
,
position
));
return
hitTestBehavior
==
PlatformViewHitTestBehavior
.
opaque
;
}
@override
bool
hitTestSelf
(
Offset
position
)
=>
hitTestBehavior
!=
PlatformViewHitTestBehavior
.
transparent
;
@override
void
handleEvent
(
PointerEvent
event
,
HitTestEntry
entry
)
{
if
(
event
is
PointerDownEvent
)
{
_gestureRecognizer
.
addPointer
(
event
);
}
}
@override
void
detach
()
{
_gestureRecognizer
.
reset
();
super
.
detach
();
}
}
packages/flutter/lib/src/services/platform_views.dart
View file @
333c9618
...
@@ -7,6 +7,7 @@ import 'dart:typed_data';
...
@@ -7,6 +7,7 @@ import 'dart:typed_data';
import
'dart:ui'
;
import
'dart:ui'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/gestures.dart'
;
import
'message_codec.dart'
;
import
'message_codec.dart'
;
import
'system_channels.dart'
;
import
'system_channels.dart'
;
...
@@ -725,4 +726,7 @@ abstract class PlatformViewController {
...
@@ -725,4 +726,7 @@ abstract class PlatformViewController {
///
///
/// See also [PlatformViewRegistry] which is a helper for managing platform view ids.
/// See also [PlatformViewRegistry] which is a helper for managing platform view ids.
int
get
viewId
;
int
get
viewId
;
/// Dispatches the `event` to the platform view.
void
dispatchPointerEvent
(
PointerEvent
event
);
}
}
packages/flutter/lib/src/widgets/platform_view.dart
View file @
333c9618
...
@@ -603,7 +603,11 @@ class PlatformViewSurface extends LeafRenderObjectWidget {
...
@@ -603,7 +603,11 @@ class PlatformViewSurface extends LeafRenderObjectWidget {
/// The [controller] must not be null.
/// The [controller] must not be null.
const
PlatformViewSurface
({
const
PlatformViewSurface
({
@required
this
.
controller
,
@required
this
.
controller
,
})
:
assert
(
controller
!=
null
);
@required
this
.
hitTestBehavior
,
@required
this
.
gestureRecognizers
,
})
:
assert
(
controller
!=
null
),
assert
(
hitTestBehavior
!=
null
),
assert
(
gestureRecognizers
!=
null
);
/// The controller for the platform view integrated by this [PlatformViewSurface].
/// The controller for the platform view integrated by this [PlatformViewSurface].
///
///
...
@@ -611,14 +615,60 @@ class PlatformViewSurface extends LeafRenderObjectWidget {
...
@@ -611,14 +615,60 @@ class PlatformViewSurface extends LeafRenderObjectWidget {
/// [PlatformViewController.viewId] identifies the platform view whose contents are painted by this widget.
/// [PlatformViewController.viewId] identifies the platform view whose contents are painted by this widget.
final
PlatformViewController
controller
;
final
PlatformViewController
controller
;
/// Which gestures should be forwarded to the PlatformView.
///
/// {@macro flutter.widgets.platformViews.gestureRecognizersDescHead}
///
/// For example, with the following setup vertical drags will not be dispatched to the platform view
/// as the vertical drag gesture is claimed by the parent [GestureDetector].
///
/// ```dart
/// GestureDetector(
/// onVerticalDragStart: (DragStartDetails details) {},
/// child: PlatformViewSurface(
/// ),
/// )
/// ```
///
/// To get the [PlatformViewSurface] to claim the vertical drag gestures we can pass a vertical drag
/// gesture recognizer factory in [gestureRecognizers] e.g:
///
/// ```dart
/// GestureDetector(
/// onVerticalDragStart: (DragStartDetails details) {},
/// child: SizedBox(
/// width: 200.0,
/// height: 100.0,
/// child: PlatformViewSurface(
/// gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>[
/// new Factory<OneSequenceGestureRecognizer>(
/// () => new EagerGestureRecognizer(),
/// ),
/// ].toSet(),
/// ),
/// ),
/// )
/// ```
///
/// {@macro flutter.widgets.platformViews.gestureRecognizersDescFoot}
// We use OneSequenceGestureRecognizers as they support gesture arena teams.
// TODO(amirh): get a list of GestureRecognizers here.
// https://github.com/flutter/flutter/issues/20953
final
Set
<
Factory
<
OneSequenceGestureRecognizer
>>
gestureRecognizers
;
/// {@macro flutter.widgets.platformViews.hittestParam}
final
PlatformViewHitTestBehavior
hitTestBehavior
;
@override
@override
RenderObject
createRenderObject
(
BuildContext
context
)
{
RenderObject
createRenderObject
(
BuildContext
context
)
{
return
PlatformViewRenderBox
(
controller:
controller
);
return
PlatformViewRenderBox
(
controller:
controller
,
gestureRecognizers:
gestureRecognizers
,
hitTestBehavior:
hitTestBehavior
);
}
}
@override
@override
void
updateRenderObject
(
BuildContext
context
,
PlatformViewRenderBox
renderObject
)
{
void
updateRenderObject
(
BuildContext
context
,
PlatformViewRenderBox
renderObject
)
{
renderObject
renderObject
..
controller
=
controller
;
..
controller
=
controller
..
hitTestBehavior
=
hitTestBehavior
..
updateGestureRecognizers
(
gestureRecognizers
);
}
}
}
}
packages/flutter/test/rendering/platform_view_test.dart
View file @
333c9618
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
import
'package:flutter/foundation.dart'
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
...
@@ -15,7 +17,16 @@ void main() {
...
@@ -15,7 +17,16 @@ void main() {
PlatformViewRenderBox
platformViewRenderBox
;
PlatformViewRenderBox
platformViewRenderBox
;
setUp
((){
setUp
((){
fakePlatformViewController
=
FakePlatformViewController
(
0
);
fakePlatformViewController
=
FakePlatformViewController
(
0
);
platformViewRenderBox
=
PlatformViewRenderBox
(
controller:
fakePlatformViewController
);
platformViewRenderBox
=
PlatformViewRenderBox
(
controller:
fakePlatformViewController
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
gestureRecognizers:
<
Factory
<
OneSequenceGestureRecognizer
>>{
Factory
<
VerticalDragGestureRecognizer
>(
()
{
return
VerticalDragGestureRecognizer
();
},
),
},);
});
});
test
(
'layout should size to max constraint'
,
()
{
test
(
'layout should size to max constraint'
,
()
{
...
...
packages/flutter/test/services/fake_platform_views.dart
View file @
333c9618
...
@@ -8,6 +8,7 @@ import 'package:collection/collection.dart';
...
@@ -8,6 +8,7 @@ import 'package:collection/collection.dart';
import
'package:flutter/painting.dart'
;
import
'package:flutter/painting.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/widgets.dart'
;
/// Used in internal testing.
/// Used in internal testing.
class
FakePlatformViewController
extends
PlatformViewController
{
class
FakePlatformViewController
extends
PlatformViewController
{
...
@@ -16,10 +17,22 @@ class FakePlatformViewController extends PlatformViewController {
...
@@ -16,10 +17,22 @@ class FakePlatformViewController extends PlatformViewController {
_id
=
id
;
_id
=
id
;
}
}
/// Events that are dispatched;
List
<
PointerEvent
>
dispatchedPointerEvents
=
<
PointerEvent
>[];
int
_id
;
int
_id
;
@override
@override
int
get
viewId
=>
_id
;
int
get
viewId
=>
_id
;
@override
void
dispatchPointerEvent
(
PointerEvent
event
)
{
dispatchedPointerEvents
.
add
(
event
);
}
void
clearTestingVariables
()
{
dispatchedPointerEvents
.
clear
();
}
}
}
class
FakeAndroidPlatformViewsController
{
class
FakeAndroidPlatformViewsController
{
...
...
packages/flutter/test/widgets/platform_view_test.dart
View file @
333c9618
...
@@ -1676,12 +1676,261 @@ void main() {
...
@@ -1676,12 +1676,261 @@ void main() {
});
});
testWidgets
(
'PlatformViewSurface should create platform view layer'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'PlatformViewSurface should create platform view layer'
,
(
WidgetTester
tester
)
async
{
final
PlatformViewSurface
surface
=
PlatformViewSurface
(
controller:
controller
);
final
PlatformViewSurface
surface
=
PlatformViewSurface
(
controller:
controller
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
gestureRecognizers:
const
<
Factory
<
OneSequenceGestureRecognizer
>>{},);
await
tester
.
pumpWidget
(
surface
);
await
tester
.
pumpWidget
(
surface
);
final
PlatformViewLayer
layer
=
tester
.
layers
.
firstWhere
((
Layer
layer
){
final
PlatformViewLayer
layer
=
tester
.
layers
.
firstWhere
((
Layer
layer
){
return
layer
is
PlatformViewLayer
;
return
layer
is
PlatformViewLayer
;
});
});
expect
(
layer
,
isNotNull
);
expect
(
layer
,
isNotNull
);
});
});
testWidgets
(
'PlatformViewSurface can lose gesture arenas'
,
(
WidgetTester
tester
)
async
{
bool
verticalDragAcceptedByParent
=
false
;
await
tester
.
pumpWidget
(
Align
(
alignment:
Alignment
.
topLeft
,
child:
Container
(
margin:
const
EdgeInsets
.
all
(
10.0
),
child:
GestureDetector
(
onVerticalDragStart:
(
DragStartDetails
d
)
{
verticalDragAcceptedByParent
=
true
;
},
child:
SizedBox
(
width:
200.0
,
height:
100.0
,
child:
PlatformViewSurface
(
controller:
controller
,
gestureRecognizers:
const
<
Factory
<
OneSequenceGestureRecognizer
>>{},
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
),
),
),
),
),
);
final
TestGesture
gesture
=
await
tester
.
startGesture
(
const
Offset
(
50.0
,
50.0
));
await
gesture
.
moveBy
(
const
Offset
(
0.0
,
100.0
));
await
gesture
.
up
();
expect
(
verticalDragAcceptedByParent
,
true
);
expect
(
controller
.
dispatchedPointerEvents
,
isEmpty
,
);
});
testWidgets
(
'PlatformViewSurface gesture recognizers dispatch events'
,
(
WidgetTester
tester
)
async
{
bool
verticalDragAcceptedByParent
=
false
;
await
tester
.
pumpWidget
(
Align
(
alignment:
Alignment
.
topLeft
,
child:
GestureDetector
(
onVerticalDragStart:
(
DragStartDetails
d
)
{
verticalDragAcceptedByParent
=
true
;
},
child:
SizedBox
(
width:
200.0
,
height:
100.0
,
child:
PlatformViewSurface
(
controller:
controller
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
gestureRecognizers:
<
Factory
<
OneSequenceGestureRecognizer
>>{
Factory
<
VerticalDragGestureRecognizer
>(
()
{
return
VerticalDragGestureRecognizer
()
..
onStart
=
(
_
)
{};
// Add callback to enable recognizer
},
),
},
),
),
),
),
);
final
TestGesture
gesture
=
await
tester
.
startGesture
(
const
Offset
(
50.0
,
50.0
));
await
gesture
.
moveBy
(
const
Offset
(
0.0
,
100.0
));
await
gesture
.
up
();
expect
(
verticalDragAcceptedByParent
,
false
);
expect
(
controller
.
dispatchedPointerEvents
.
length
,
3
,
);
});
testWidgets
(
'PlatformViewSurface can claim gesture after all pointers are up'
,
(
WidgetTester
tester
)
async
{
bool
verticalDragAcceptedByParent
=
false
;
// The long press recognizer rejects the gesture after the PlatformViewSurface gets the pointer up event.
// This test makes sure that the PlatformViewSurface can win the gesture after it got the pointer up event.
await
tester
.
pumpWidget
(
Align
(
alignment:
Alignment
.
topLeft
,
child:
GestureDetector
(
onVerticalDragStart:
(
DragStartDetails
d
)
{
verticalDragAcceptedByParent
=
true
;
},
onLongPress:
()
{
},
child:
SizedBox
(
width:
200.0
,
height:
100.0
,
child:
PlatformViewSurface
(
controller:
controller
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
gestureRecognizers:
const
<
Factory
<
OneSequenceGestureRecognizer
>>{},
),
),
),
),
);
final
TestGesture
gesture
=
await
tester
.
startGesture
(
const
Offset
(
50.0
,
50.0
));
await
gesture
.
up
();
expect
(
verticalDragAcceptedByParent
,
false
);
expect
(
controller
.
dispatchedPointerEvents
.
length
,
2
,
);
});
testWidgets
(
'PlatformViewSurface rebuilt during gesture'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
Align
(
alignment:
Alignment
.
topLeft
,
child:
SizedBox
(
width:
200.0
,
height:
100.0
,
child:
PlatformViewSurface
(
controller:
controller
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
gestureRecognizers:
const
<
Factory
<
OneSequenceGestureRecognizer
>>{},
),
),
),
);
final
TestGesture
gesture
=
await
tester
.
startGesture
(
const
Offset
(
50.0
,
50.0
));
await
gesture
.
moveBy
(
const
Offset
(
0.0
,
100.0
));
await
tester
.
pumpWidget
(
Align
(
alignment:
Alignment
.
topLeft
,
child:
SizedBox
(
width:
200.0
,
height:
100.0
,
child:
PlatformViewSurface
(
controller:
controller
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
gestureRecognizers:
const
<
Factory
<
OneSequenceGestureRecognizer
>>{},
),
),
),
);
await
gesture
.
up
();
expect
(
controller
.
dispatchedPointerEvents
.
length
,
3
,
);
});
testWidgets
(
'PlatformViewSurface with eager gesture recognizer'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
Align
(
alignment:
Alignment
.
topLeft
,
child:
GestureDetector
(
onVerticalDragStart:
(
DragStartDetails
d
)
{
},
child:
SizedBox
(
width:
200.0
,
height:
100.0
,
child:
PlatformViewSurface
(
controller:
controller
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
gestureRecognizers:
<
Factory
<
OneSequenceGestureRecognizer
>>{
Factory
<
OneSequenceGestureRecognizer
>(
()
=>
EagerGestureRecognizer
(),
),
},
),
),
),
),
);
await
tester
.
startGesture
(
const
Offset
(
50.0
,
50.0
));
// Normally (without the eager gesture recognizer) after just the pointer down event
// no gesture arena member will claim the arena (so no motion events will be dispatched to
// the PlatformViewSurface). Here we assert that with the eager recognizer in the gesture team the
// pointer down event is immediately dispatched.
expect
(
controller
.
dispatchedPointerEvents
.
length
,
1
,
);
});
testWidgets
(
'PlatformViewRenderBox reconstructed with same gestureRecognizers'
,
(
WidgetTester
tester
)
async
{
int
factoryInvocationCount
=
0
;
final
ValueGetter
<
EagerGestureRecognizer
>
constructRecognizer
=
()
{
++
factoryInvocationCount
;
return
EagerGestureRecognizer
();
};
final
PlatformViewSurface
platformViewSurface
=
PlatformViewSurface
(
controller:
controller
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
gestureRecognizers:
<
Factory
<
OneSequenceGestureRecognizer
>>{
Factory
<
OneSequenceGestureRecognizer
>(
constructRecognizer
,
),
});
await
tester
.
pumpWidget
(
platformViewSurface
);
await
tester
.
pumpWidget
(
const
SizedBox
.
shrink
());
await
tester
.
pumpWidget
(
platformViewSurface
);
expect
(
factoryInvocationCount
,
2
);
});
testWidgets
(
'PlatformViewSurface rebuilt with same gestureRecognizers'
,
(
WidgetTester
tester
)
async
{
int
factoryInvocationCount
=
0
;
final
ValueGetter
<
EagerGestureRecognizer
>
constructRecognizer
=
()
{
++
factoryInvocationCount
;
return
EagerGestureRecognizer
();
};
await
tester
.
pumpWidget
(
PlatformViewSurface
(
controller:
controller
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
gestureRecognizers:
<
Factory
<
OneSequenceGestureRecognizer
>>{
Factory
<
OneSequenceGestureRecognizer
>(
constructRecognizer
,
),
})
);
await
tester
.
pumpWidget
(
PlatformViewSurface
(
controller:
controller
,
hitTestBehavior:
PlatformViewHitTestBehavior
.
opaque
,
gestureRecognizers:
<
Factory
<
OneSequenceGestureRecognizer
>>{
Factory
<
OneSequenceGestureRecognizer
>(
constructRecognizer
,
),
})
);
expect
(
factoryInvocationCount
,
1
);
});
});
});
}
}
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