mirror of
https://github.com/flutter/packages.git
synced 2025-06-30 06:37:17 +08:00
Merge NNBD branch into master (#270)
This commit is contained in:

committed by
GitHub

parent
1c7d23bdbe
commit
f3e92fded0
@ -7,6 +7,9 @@ task:
|
|||||||
upgrade_script:
|
upgrade_script:
|
||||||
- flutter channel master
|
- flutter channel master
|
||||||
- flutter upgrade
|
- flutter upgrade
|
||||||
|
# TODO(goderbauer): Remove next two lines when https://github.com/flutter/flutter/issues/74772 is resolved.
|
||||||
|
- rm -rf /home/cirrus/sdks/flutter/bin/cache
|
||||||
|
- flutter doctor
|
||||||
- git fetch origin master
|
- git fetch origin master
|
||||||
activate_script: pub global activate flutter_plugin_tools
|
activate_script: pub global activate flutter_plugin_tools
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [2.0.0-nullsafety.0] - November 16, 2020
|
||||||
|
|
||||||
|
* Migrates to null safety.
|
||||||
|
|
||||||
## [1.1.2] - July 28, 2020
|
## [1.1.2] - July 28, 2020
|
||||||
|
|
||||||
* Fixes for upcoming changes to the flutter framework.
|
* Fixes for upcoming changes to the flutter framework.
|
||||||
|
@ -50,7 +50,7 @@ class _OpenContainerTransformDemoState
|
|||||||
extends State<OpenContainerTransformDemo> {
|
extends State<OpenContainerTransformDemo> {
|
||||||
ContainerTransitionType _transitionType = ContainerTransitionType.fade;
|
ContainerTransitionType _transitionType = ContainerTransitionType.fade;
|
||||||
|
|
||||||
void _showMarkedAsDoneSnackbar(bool isMarkedAsDone) {
|
void _showMarkedAsDoneSnackbar(bool? isMarkedAsDone) {
|
||||||
if (isMarkedAsDone ?? false)
|
if (isMarkedAsDone ?? false)
|
||||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
||||||
content: Text('Marked as done!'),
|
content: Text('Marked as done!'),
|
||||||
@ -271,14 +271,14 @@ class _OpenContainerTransformDemoState
|
|||||||
|
|
||||||
class _OpenContainerWrapper extends StatelessWidget {
|
class _OpenContainerWrapper extends StatelessWidget {
|
||||||
const _OpenContainerWrapper({
|
const _OpenContainerWrapper({
|
||||||
this.closedBuilder,
|
required this.closedBuilder,
|
||||||
this.transitionType,
|
required this.transitionType,
|
||||||
this.onClosed,
|
required this.onClosed,
|
||||||
});
|
});
|
||||||
|
|
||||||
final OpenContainerBuilder closedBuilder;
|
final CloseContainerBuilder closedBuilder;
|
||||||
final ContainerTransitionType transitionType;
|
final ContainerTransitionType transitionType;
|
||||||
final ClosedCallback<bool> onClosed;
|
final ClosedCallback<bool?> onClosed;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -295,7 +295,7 @@ class _OpenContainerWrapper extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ExampleCard extends StatelessWidget {
|
class _ExampleCard extends StatelessWidget {
|
||||||
const _ExampleCard({this.openContainer});
|
const _ExampleCard({required this.openContainer});
|
||||||
|
|
||||||
final VoidCallback openContainer;
|
final VoidCallback openContainer;
|
||||||
|
|
||||||
@ -333,7 +333,7 @@ class _ExampleCard extends StatelessWidget {
|
|||||||
'adipiscing elit, sed do eiusmod tempor.',
|
'adipiscing elit, sed do eiusmod tempor.',
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodyText2
|
.bodyText2!
|
||||||
.copyWith(color: Colors.black54),
|
.copyWith(color: Colors.black54),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -345,8 +345,8 @@ class _ExampleCard extends StatelessWidget {
|
|||||||
|
|
||||||
class _SmallerCard extends StatelessWidget {
|
class _SmallerCard extends StatelessWidget {
|
||||||
const _SmallerCard({
|
const _SmallerCard({
|
||||||
this.openContainer,
|
required this.openContainer,
|
||||||
this.subtitle,
|
required this.subtitle,
|
||||||
});
|
});
|
||||||
|
|
||||||
final VoidCallback openContainer;
|
final VoidCallback openContainer;
|
||||||
@ -397,7 +397,7 @@ class _SmallerCard extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ExampleSingleTile extends StatelessWidget {
|
class _ExampleSingleTile extends StatelessWidget {
|
||||||
const _ExampleSingleTile({this.openContainer});
|
const _ExampleSingleTile({required this.openContainer});
|
||||||
|
|
||||||
final VoidCallback openContainer;
|
final VoidCallback openContainer;
|
||||||
|
|
||||||
@ -454,10 +454,10 @@ class _InkWellOverlay extends StatelessWidget {
|
|||||||
this.child,
|
this.child,
|
||||||
});
|
});
|
||||||
|
|
||||||
final VoidCallback openContainer;
|
final VoidCallback? openContainer;
|
||||||
final double width;
|
final double? width;
|
||||||
final double height;
|
final double? height;
|
||||||
final Widget child;
|
final Widget? child;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -510,7 +510,7 @@ class _DetailsPage extends StatelessWidget {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
'Title',
|
'Title',
|
||||||
style: Theme.of(context).textTheme.headline5.copyWith(
|
style: Theme.of(context).textTheme.headline5!.copyWith(
|
||||||
color: Colors.black54,
|
color: Colors.black54,
|
||||||
fontSize: 30.0,
|
fontSize: 30.0,
|
||||||
),
|
),
|
||||||
@ -518,7 +518,7 @@ class _DetailsPage extends StatelessWidget {
|
|||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
Text(
|
Text(
|
||||||
_loremIpsumParagraph,
|
_loremIpsumParagraph,
|
||||||
style: Theme.of(context).textTheme.bodyText2.copyWith(
|
style: Theme.of(context).textTheme.bodyText2!.copyWith(
|
||||||
color: Colors.black54,
|
color: Colors.black54,
|
||||||
height: 1.5,
|
height: 1.5,
|
||||||
fontSize: 16.0,
|
fontSize: 16.0,
|
||||||
|
@ -14,7 +14,7 @@ class FadeScaleTransitionDemo extends StatefulWidget {
|
|||||||
|
|
||||||
class _FadeScaleTransitionDemoState extends State<FadeScaleTransitionDemo>
|
class _FadeScaleTransitionDemoState extends State<FadeScaleTransitionDemo>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
AnimationController _controller;
|
late AnimationController _controller;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -48,8 +48,6 @@ class _FadeScaleTransitionDemoState extends State<FadeScaleTransitionDemo>
|
|||||||
case AnimationStatus.dismissed:
|
case AnimationStatus.dismissed:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assert(false);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -58,7 +56,7 @@ class _FadeScaleTransitionDemoState extends State<FadeScaleTransitionDemo>
|
|||||||
appBar: AppBar(title: const Text('Fade')),
|
appBar: AppBar(title: const Text('Fade')),
|
||||||
floatingActionButton: AnimatedBuilder(
|
floatingActionButton: AnimatedBuilder(
|
||||||
animation: _controller,
|
animation: _controller,
|
||||||
builder: (BuildContext context, Widget child) {
|
builder: (BuildContext context, Widget? child) {
|
||||||
return FadeScaleTransition(
|
return FadeScaleTransition(
|
||||||
animation: _controller,
|
animation: _controller,
|
||||||
child: child,
|
child: child,
|
||||||
|
@ -126,11 +126,11 @@ class _TransitionsHomePageState extends State<_TransitionsHomePage> {
|
|||||||
class _TransitionListTile extends StatelessWidget {
|
class _TransitionListTile extends StatelessWidget {
|
||||||
const _TransitionListTile({
|
const _TransitionListTile({
|
||||||
this.onTap,
|
this.onTap,
|
||||||
this.title,
|
required this.title,
|
||||||
this.subtitle,
|
required this.subtitle,
|
||||||
});
|
});
|
||||||
|
|
||||||
final GestureTapCallback onTap;
|
final GestureTapCallback? onTap;
|
||||||
final String title;
|
final String title;
|
||||||
final String subtitle;
|
final String subtitle;
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@ class SharedAxisTransitionDemo extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SharedAxisTransitionDemoState extends State<SharedAxisTransitionDemo> {
|
class _SharedAxisTransitionDemoState extends State<SharedAxisTransitionDemo> {
|
||||||
SharedAxisTransitionType _transitionType =
|
SharedAxisTransitionType? _transitionType =
|
||||||
SharedAxisTransitionType.horizontal;
|
SharedAxisTransitionType.horizontal;
|
||||||
bool _isLoggedIn = false;
|
bool _isLoggedIn = false;
|
||||||
|
|
||||||
void _updateTransitionType(SharedAxisTransitionType newType) {
|
void _updateTransitionType(SharedAxisTransitionType? newType) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_transitionType = newType;
|
_transitionType = newType;
|
||||||
});
|
});
|
||||||
@ -51,7 +51,7 @@ class _SharedAxisTransitionDemoState extends State<SharedAxisTransitionDemo> {
|
|||||||
child: child,
|
child: child,
|
||||||
animation: animation,
|
animation: animation,
|
||||||
secondaryAnimation: secondaryAnimation,
|
secondaryAnimation: secondaryAnimation,
|
||||||
transitionType: _transitionType,
|
transitionType: _transitionType!,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: _isLoggedIn ? _CoursePage() : _SignInPage(),
|
child: _isLoggedIn ? _CoursePage() : _SignInPage(),
|
||||||
@ -80,7 +80,7 @@ class _SharedAxisTransitionDemoState extends State<SharedAxisTransitionDemo> {
|
|||||||
Radio<SharedAxisTransitionType>(
|
Radio<SharedAxisTransitionType>(
|
||||||
value: SharedAxisTransitionType.horizontal,
|
value: SharedAxisTransitionType.horizontal,
|
||||||
groupValue: _transitionType,
|
groupValue: _transitionType,
|
||||||
onChanged: (SharedAxisTransitionType newValue) {
|
onChanged: (SharedAxisTransitionType? newValue) {
|
||||||
_updateTransitionType(newValue);
|
_updateTransitionType(newValue);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -88,7 +88,7 @@ class _SharedAxisTransitionDemoState extends State<SharedAxisTransitionDemo> {
|
|||||||
Radio<SharedAxisTransitionType>(
|
Radio<SharedAxisTransitionType>(
|
||||||
value: SharedAxisTransitionType.vertical,
|
value: SharedAxisTransitionType.vertical,
|
||||||
groupValue: _transitionType,
|
groupValue: _transitionType,
|
||||||
onChanged: (SharedAxisTransitionType newValue) {
|
onChanged: (SharedAxisTransitionType? newValue) {
|
||||||
_updateTransitionType(newValue);
|
_updateTransitionType(newValue);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -96,7 +96,7 @@ class _SharedAxisTransitionDemoState extends State<SharedAxisTransitionDemo> {
|
|||||||
Radio<SharedAxisTransitionType>(
|
Radio<SharedAxisTransitionType>(
|
||||||
value: SharedAxisTransitionType.scaled,
|
value: SharedAxisTransitionType.scaled,
|
||||||
groupValue: _transitionType,
|
groupValue: _transitionType,
|
||||||
onChanged: (SharedAxisTransitionType newValue) {
|
onChanged: (SharedAxisTransitionType? newValue) {
|
||||||
_updateTransitionType(newValue);
|
_updateTransitionType(newValue);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -146,7 +146,7 @@ class _CoursePage extends StatelessWidget {
|
|||||||
|
|
||||||
class _CourseSwitch extends StatefulWidget {
|
class _CourseSwitch extends StatefulWidget {
|
||||||
const _CourseSwitch({
|
const _CourseSwitch({
|
||||||
this.course,
|
required this.course,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String course;
|
final String course;
|
||||||
|
@ -6,7 +6,7 @@ publish_to: none
|
|||||||
version: 0.0.1
|
version: 0.0.1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.3.0 <3.0.0"
|
sdk: ">=2.12.0-0 <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
animations:
|
animations:
|
||||||
|
@ -1,203 +0,0 @@
|
|||||||
// Copyright 2020 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// TODO(shihaohong): Remove DualTransitionBuilder once flutter/flutter's `stable`
|
|
||||||
// branch contains DualTransitionBuilder.
|
|
||||||
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
|
|
||||||
/// Builder callback used by [DualTransitionBuilder].
|
|
||||||
///
|
|
||||||
/// The builder is expected to return a transition powered by the provided
|
|
||||||
/// `animation` and wrapping the provided `child`.
|
|
||||||
///
|
|
||||||
/// The `animation` provided to the builder always runs forward from 0.0 to 1.0.
|
|
||||||
typedef TransitionBuilder = Widget Function(
|
|
||||||
BuildContext context,
|
|
||||||
Animation<double> animation,
|
|
||||||
Widget child,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// A transition builder that animates its [child] based on the
|
|
||||||
/// [AnimationStatus] of the provided [animation].
|
|
||||||
///
|
|
||||||
/// This widget can be used to specify different enter and exit transitions for
|
|
||||||
/// a [child].
|
|
||||||
///
|
|
||||||
/// While the [animation] runs forward, the [child] is animated according to
|
|
||||||
/// [forwardBuilder] and while the [animation] is running in reverse, it is
|
|
||||||
/// animated according to [reverseBuilder].
|
|
||||||
///
|
|
||||||
/// Using this builder allows the widget tree to maintain its shape by nesting
|
|
||||||
/// the enter and exit transitions. This ensures that no state information of
|
|
||||||
/// any descendant widget is lost when the transition starts or completes.
|
|
||||||
class DualTransitionBuilder extends StatefulWidget {
|
|
||||||
/// Creates a [DualTransitionBuilder].
|
|
||||||
///
|
|
||||||
/// The [animation], [forwardBuilder], and [reverseBuilder] arguments are
|
|
||||||
/// required and must not be null.
|
|
||||||
const DualTransitionBuilder({
|
|
||||||
Key key,
|
|
||||||
@required this.animation,
|
|
||||||
@required this.forwardBuilder,
|
|
||||||
@required this.reverseBuilder,
|
|
||||||
this.child,
|
|
||||||
}) : assert(animation != null),
|
|
||||||
assert(forwardBuilder != null),
|
|
||||||
assert(reverseBuilder != null),
|
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
/// The animation that drives the [child]'s transition.
|
|
||||||
///
|
|
||||||
/// When this animation runs forward, the [child] transitions as specified by
|
|
||||||
/// [forwardBuilder]. When it runs in reverse, the child transitions according
|
|
||||||
/// to [reverseBuilder].
|
|
||||||
final Animation<double> animation;
|
|
||||||
|
|
||||||
/// A builder for the transition that makes [child] appear on screen.
|
|
||||||
///
|
|
||||||
/// The [child] should be fully visible when the provided `animation` reaches
|
|
||||||
/// 1.0.
|
|
||||||
///
|
|
||||||
/// The `animation` provided to this builder is running forward from 0.0 to
|
|
||||||
/// 1.0 when [animation] runs _forward_. When [animation] runs in reverse,
|
|
||||||
/// the given `animation` is set to [kAlwaysCompleteAnimation].
|
|
||||||
///
|
|
||||||
/// See also:
|
|
||||||
///
|
|
||||||
/// * [reverseBuilder], which builds the transition for making the [child]
|
|
||||||
/// disappear from the screen.
|
|
||||||
final TransitionBuilder forwardBuilder;
|
|
||||||
|
|
||||||
/// A builder for a transition that makes [child] disappear from the screen.
|
|
||||||
///
|
|
||||||
/// The [child] should be fully invisible when the provided `animation`
|
|
||||||
/// reaches 1.0.
|
|
||||||
///
|
|
||||||
/// The `animation` provided to this builder is running forward from 0.0 to
|
|
||||||
/// 1.0 when [animation] runs in _reverse_. When [animation] runs forward,
|
|
||||||
/// the given `animation` is set to [kAlwaysDismissedAnimation].
|
|
||||||
///
|
|
||||||
/// See also:
|
|
||||||
///
|
|
||||||
/// * [forwardBuilder], which builds the transition for making the [child]
|
|
||||||
/// appear on screen.
|
|
||||||
final TransitionBuilder reverseBuilder;
|
|
||||||
|
|
||||||
/// The widget below this [DualTransitionBuilder] in the tree.
|
|
||||||
///
|
|
||||||
/// This child widget will be wrapped by the transitions built by
|
|
||||||
/// [forwardBuilder] and [reverseBuilder].
|
|
||||||
final Widget child;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<DualTransitionBuilder> createState() => _DualTransitionBuilderState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DualTransitionBuilderState extends State<DualTransitionBuilder> {
|
|
||||||
AnimationStatus _effectiveAnimationStatus;
|
|
||||||
final ProxyAnimation _forwardAnimation = ProxyAnimation();
|
|
||||||
final ProxyAnimation _reverseAnimation = ProxyAnimation();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_effectiveAnimationStatus = widget.animation.status;
|
|
||||||
widget.animation.addStatusListener(_animationListener);
|
|
||||||
_updateAnimations();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _animationListener(AnimationStatus animationStatus) {
|
|
||||||
final AnimationStatus oldEffective = _effectiveAnimationStatus;
|
|
||||||
_effectiveAnimationStatus = _calculateEffectiveAnimationStatus(
|
|
||||||
lastEffective: _effectiveAnimationStatus,
|
|
||||||
current: animationStatus,
|
|
||||||
);
|
|
||||||
if (oldEffective != _effectiveAnimationStatus) {
|
|
||||||
_updateAnimations();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didUpdateWidget(DualTransitionBuilder oldWidget) {
|
|
||||||
super.didUpdateWidget(oldWidget);
|
|
||||||
if (oldWidget.animation != widget.animation) {
|
|
||||||
oldWidget.animation.removeStatusListener(_animationListener);
|
|
||||||
widget.animation.addStatusListener(_animationListener);
|
|
||||||
_animationListener(widget.animation.status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// When a transition is interrupted midway we just want to play the ongoing
|
|
||||||
// animation in reverse. Switching to the actual reverse transition would
|
|
||||||
// yield a disjoint experience since the forward and reverse transitions are
|
|
||||||
// very different.
|
|
||||||
AnimationStatus _calculateEffectiveAnimationStatus({
|
|
||||||
@required AnimationStatus lastEffective,
|
|
||||||
@required AnimationStatus current,
|
|
||||||
}) {
|
|
||||||
assert(current != null);
|
|
||||||
assert(lastEffective != null);
|
|
||||||
switch (current) {
|
|
||||||
case AnimationStatus.dismissed:
|
|
||||||
case AnimationStatus.completed:
|
|
||||||
return current;
|
|
||||||
case AnimationStatus.forward:
|
|
||||||
switch (lastEffective) {
|
|
||||||
case AnimationStatus.dismissed:
|
|
||||||
case AnimationStatus.completed:
|
|
||||||
case AnimationStatus.forward:
|
|
||||||
return current;
|
|
||||||
case AnimationStatus.reverse:
|
|
||||||
return lastEffective;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AnimationStatus.reverse:
|
|
||||||
switch (lastEffective) {
|
|
||||||
case AnimationStatus.dismissed:
|
|
||||||
case AnimationStatus.completed:
|
|
||||||
case AnimationStatus.reverse:
|
|
||||||
return current;
|
|
||||||
case AnimationStatus.forward:
|
|
||||||
return lastEffective;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return null; // unreachable
|
|
||||||
}
|
|
||||||
|
|
||||||
void _updateAnimations() {
|
|
||||||
switch (_effectiveAnimationStatus) {
|
|
||||||
case AnimationStatus.dismissed:
|
|
||||||
case AnimationStatus.forward:
|
|
||||||
_forwardAnimation.parent = widget.animation;
|
|
||||||
_reverseAnimation.parent = kAlwaysDismissedAnimation;
|
|
||||||
break;
|
|
||||||
case AnimationStatus.reverse:
|
|
||||||
case AnimationStatus.completed:
|
|
||||||
_forwardAnimation.parent = kAlwaysCompleteAnimation;
|
|
||||||
_reverseAnimation.parent = ReverseAnimation(widget.animation);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
widget.animation.removeStatusListener(_animationListener);
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return widget.forwardBuilder(
|
|
||||||
context,
|
|
||||||
_forwardAnimation,
|
|
||||||
widget.reverseBuilder(
|
|
||||||
context,
|
|
||||||
_reverseAnimation,
|
|
||||||
widget.child,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,14 +2,9 @@
|
|||||||
// 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/material.dart'
|
import 'package:flutter/material.dart';
|
||||||
hide decelerateEasing; // ignore: undefined_hidden_name
|
import 'package:flutter/widgets.dart';
|
||||||
// TODO(goderbauer): Remove implementation import when material properly exports the file.
|
|
||||||
import 'package:flutter/src/material/curves.dart'; // ignore: implementation_imports
|
|
||||||
|
|
||||||
// TODO(shihaohong): Remove DualTransitionBuilder once flutter/flutter's `stable`
|
|
||||||
// branch contains DualTransitionBuilder.
|
|
||||||
import 'dual_transition_builder.dart' as dual_transition_builder;
|
|
||||||
import 'modal.dart';
|
import 'modal.dart';
|
||||||
|
|
||||||
/// The modal transition configuration for a Material fade transition.
|
/// The modal transition configuration for a Material fade transition.
|
||||||
@ -121,11 +116,10 @@ class FadeScaleTransition extends StatelessWidget {
|
|||||||
/// [animation] is typically an [AnimationController] that drives the transition
|
/// [animation] is typically an [AnimationController] that drives the transition
|
||||||
/// animation. [animation] cannot be null.
|
/// animation. [animation] cannot be null.
|
||||||
const FadeScaleTransition({
|
const FadeScaleTransition({
|
||||||
Key key,
|
Key? key,
|
||||||
@required this.animation,
|
required this.animation,
|
||||||
this.child,
|
this.child,
|
||||||
}) : assert(animation != null),
|
}) : super(key: key);
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
/// The animation that drives the [child]'s entrance and exit.
|
/// The animation that drives the [child]'s entrance and exit.
|
||||||
///
|
///
|
||||||
@ -139,7 +133,7 @@ class FadeScaleTransition extends StatelessWidget {
|
|||||||
///
|
///
|
||||||
/// This widget will transition in and out as driven by [animation] and
|
/// This widget will transition in and out as driven by [animation] and
|
||||||
/// [secondaryAnimation].
|
/// [secondaryAnimation].
|
||||||
final Widget child;
|
final Widget? child;
|
||||||
|
|
||||||
static final Animatable<double> _fadeInTransition = CurveTween(
|
static final Animatable<double> _fadeInTransition = CurveTween(
|
||||||
curve: const Interval(0.0, 0.3),
|
curve: const Interval(0.0, 0.3),
|
||||||
@ -155,12 +149,12 @@ class FadeScaleTransition extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return dual_transition_builder.DualTransitionBuilder(
|
return DualTransitionBuilder(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
forwardBuilder: (
|
forwardBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
opacity: _fadeInTransition.animate(animation),
|
opacity: _fadeInTransition.animate(animation),
|
||||||
@ -173,7 +167,7 @@ class FadeScaleTransition extends StatelessWidget {
|
|||||||
reverseBuilder: (
|
reverseBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
opacity: _fadeOutTransition.animate(animation),
|
opacity: _fadeOutTransition.animate(animation),
|
||||||
|
@ -3,10 +3,7 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
// TODO(shihaohong): Remove DualTransitionBuilder once flutter/flutter's `stable`
|
|
||||||
// branch contains DualTransitionBuilder.
|
|
||||||
import 'dual_transition_builder.dart' as dual_transition_builder;
|
|
||||||
|
|
||||||
/// Used by [PageTransitionsTheme] to define a page route transition animation
|
/// Used by [PageTransitionsTheme] to define a page route transition animation
|
||||||
/// in which the outgoing page fades out, then the incoming page fades in and
|
/// in which the outgoing page fades out, then the incoming page fades in and
|
||||||
@ -69,12 +66,12 @@ class FadeThroughPageTransitionsBuilder extends PageTransitionsBuilder {
|
|||||||
/// The color to use for the background color during the transition.
|
/// The color to use for the background color during the transition.
|
||||||
///
|
///
|
||||||
/// This defaults to the [Theme]'s [ThemeData.canvasColor].
|
/// This defaults to the [Theme]'s [ThemeData.canvasColor].
|
||||||
final Color fillColor;
|
final Color? fillColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildTransitions<T>(
|
Widget buildTransitions<T>(
|
||||||
PageRoute<T> route,
|
PageRoute<T>? route,
|
||||||
BuildContext context,
|
BuildContext? context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Animation<double> secondaryAnimation,
|
Animation<double> secondaryAnimation,
|
||||||
Widget child,
|
Widget child,
|
||||||
@ -166,12 +163,11 @@ class FadeThroughTransition extends StatelessWidget {
|
|||||||
/// The [animation] and [secondaryAnimation] argument are required and must
|
/// The [animation] and [secondaryAnimation] argument are required and must
|
||||||
/// not be null.
|
/// not be null.
|
||||||
const FadeThroughTransition({
|
const FadeThroughTransition({
|
||||||
@required this.animation,
|
required this.animation,
|
||||||
@required this.secondaryAnimation,
|
required this.secondaryAnimation,
|
||||||
this.fillColor,
|
this.fillColor,
|
||||||
this.child,
|
this.child,
|
||||||
}) : assert(animation != null),
|
});
|
||||||
assert(secondaryAnimation != null);
|
|
||||||
|
|
||||||
/// The animation that drives the [child]'s entrance and exit.
|
/// The animation that drives the [child]'s entrance and exit.
|
||||||
///
|
///
|
||||||
@ -193,13 +189,13 @@ class FadeThroughTransition extends StatelessWidget {
|
|||||||
/// The color to use for the background color during the transition.
|
/// The color to use for the background color during the transition.
|
||||||
///
|
///
|
||||||
/// This defaults to the [Theme]'s [ThemeData.canvasColor].
|
/// This defaults to the [Theme]'s [ThemeData.canvasColor].
|
||||||
final Color fillColor;
|
final Color? fillColor;
|
||||||
|
|
||||||
/// The widget below this widget in the tree.
|
/// The widget below this widget in the tree.
|
||||||
///
|
///
|
||||||
/// This widget will transition in and out as driven by [animation] and
|
/// This widget will transition in and out as driven by [animation] and
|
||||||
/// [secondaryAnimation].
|
/// [secondaryAnimation].
|
||||||
final Widget child;
|
final Widget? child;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -217,20 +213,20 @@ class FadeThroughTransition extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ZoomedFadeInFadeOut extends StatelessWidget {
|
class _ZoomedFadeInFadeOut extends StatelessWidget {
|
||||||
const _ZoomedFadeInFadeOut({Key key, this.animation, this.child})
|
const _ZoomedFadeInFadeOut({Key? key, required this.animation, this.child})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
final Animation<double> animation;
|
final Animation<double> animation;
|
||||||
final Widget child;
|
final Widget? child;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return dual_transition_builder.DualTransitionBuilder(
|
return DualTransitionBuilder(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
forwardBuilder: (
|
forwardBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return _ZoomedFadeIn(
|
return _ZoomedFadeIn(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
@ -240,7 +236,7 @@ class _ZoomedFadeInFadeOut extends StatelessWidget {
|
|||||||
reverseBuilder: (
|
reverseBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return _FadeOut(
|
return _FadeOut(
|
||||||
child: child,
|
child: child,
|
||||||
@ -255,10 +251,10 @@ class _ZoomedFadeInFadeOut extends StatelessWidget {
|
|||||||
class _ZoomedFadeIn extends StatelessWidget {
|
class _ZoomedFadeIn extends StatelessWidget {
|
||||||
const _ZoomedFadeIn({
|
const _ZoomedFadeIn({
|
||||||
this.child,
|
this.child,
|
||||||
this.animation,
|
required this.animation,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Widget child;
|
final Widget? child;
|
||||||
final Animation<double> animation;
|
final Animation<double> animation;
|
||||||
|
|
||||||
static final CurveTween _inCurve = CurveTween(
|
static final CurveTween _inCurve = CurveTween(
|
||||||
@ -304,10 +300,10 @@ class _ZoomedFadeIn extends StatelessWidget {
|
|||||||
class _FadeOut extends StatelessWidget {
|
class _FadeOut extends StatelessWidget {
|
||||||
const _FadeOut({
|
const _FadeOut({
|
||||||
this.child,
|
this.child,
|
||||||
this.animation,
|
required this.animation,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Widget child;
|
final Widget? child;
|
||||||
final Animation<double> animation;
|
final Animation<double> animation;
|
||||||
|
|
||||||
static final CurveTween _outCurve = CurveTween(
|
static final CurveTween _outCurve = CurveTween(
|
||||||
|
@ -46,15 +46,13 @@ typedef _ModalTransitionBuilder = Widget Function(
|
|||||||
///
|
///
|
||||||
/// * [ModalConfiguration], which is the configuration object used to define
|
/// * [ModalConfiguration], which is the configuration object used to define
|
||||||
/// the modal's characteristics.
|
/// the modal's characteristics.
|
||||||
Future<T> showModal<T>({
|
Future<T?> showModal<T>({
|
||||||
@required BuildContext context,
|
required BuildContext context,
|
||||||
ModalConfiguration configuration = const FadeScaleTransitionConfiguration(),
|
ModalConfiguration configuration = const FadeScaleTransitionConfiguration(),
|
||||||
bool useRootNavigator = true,
|
bool useRootNavigator = true,
|
||||||
WidgetBuilder builder,
|
required WidgetBuilder builder,
|
||||||
}) {
|
}) {
|
||||||
assert(configuration != null);
|
String? barrierLabel = configuration.barrierLabel;
|
||||||
assert(useRootNavigator != null);
|
|
||||||
String barrierLabel = configuration.barrierLabel;
|
|
||||||
// Avoid looking up [MaterialLocalizations.of(context).modalBarrierDismissLabel]
|
// Avoid looking up [MaterialLocalizations.of(context).modalBarrierDismissLabel]
|
||||||
// if there is no dismissible barrier.
|
// if there is no dismissible barrier.
|
||||||
if (configuration.barrierDismissible && configuration.barrierLabel == null) {
|
if (configuration.barrierDismissible && configuration.barrierLabel == null) {
|
||||||
@ -89,22 +87,21 @@ class _ModalRoute<T> extends PopupRoute<T> {
|
|||||||
this.barrierColor,
|
this.barrierColor,
|
||||||
this.barrierDismissible = true,
|
this.barrierDismissible = true,
|
||||||
this.barrierLabel,
|
this.barrierLabel,
|
||||||
this.transitionDuration,
|
required this.transitionDuration,
|
||||||
this.reverseTransitionDuration,
|
required this.reverseTransitionDuration,
|
||||||
_ModalTransitionBuilder transitionBuilder,
|
required _ModalTransitionBuilder transitionBuilder,
|
||||||
@required this.builder,
|
required this.builder,
|
||||||
}) : assert(barrierDismissible != null),
|
}) : assert(!barrierDismissible || barrierLabel != null),
|
||||||
assert(!barrierDismissible || barrierLabel != null),
|
|
||||||
_transitionBuilder = transitionBuilder;
|
_transitionBuilder = transitionBuilder;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Color barrierColor;
|
final Color? barrierColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final bool barrierDismissible;
|
final bool barrierDismissible;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String barrierLabel;
|
final String? barrierLabel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Duration transitionDuration;
|
final Duration transitionDuration;
|
||||||
@ -129,7 +126,7 @@ class _ModalRoute<T> extends PopupRoute<T> {
|
|||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
final Widget child = Builder(builder: builder);
|
final Widget child = Builder(builder: builder);
|
||||||
return theme != null ? Theme(data: theme, child: child) : child;
|
return Theme(data: theme, child: child);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -178,16 +175,12 @@ abstract class ModalConfiguration {
|
|||||||
/// application. [transitionDuration] and [reverseTransitionDuration]
|
/// application. [transitionDuration] and [reverseTransitionDuration]
|
||||||
/// cannot be null.
|
/// cannot be null.
|
||||||
const ModalConfiguration({
|
const ModalConfiguration({
|
||||||
@required this.barrierColor,
|
required this.barrierColor,
|
||||||
@required this.barrierDismissible,
|
required this.barrierDismissible,
|
||||||
this.barrierLabel,
|
this.barrierLabel,
|
||||||
@required this.transitionDuration,
|
required this.transitionDuration,
|
||||||
@required this.reverseTransitionDuration,
|
required this.reverseTransitionDuration,
|
||||||
}) : assert(barrierColor != null),
|
}) : assert(!barrierDismissible || barrierLabel != null);
|
||||||
assert(barrierDismissible != null),
|
|
||||||
assert(!barrierDismissible || barrierLabel != null),
|
|
||||||
assert(transitionDuration != null),
|
|
||||||
assert(reverseTransitionDuration != null);
|
|
||||||
|
|
||||||
/// The color to use for the modal barrier. If this is null, the barrier will
|
/// The color to use for the modal barrier. If this is null, the barrier will
|
||||||
/// be transparent.
|
/// be transparent.
|
||||||
@ -197,7 +190,7 @@ abstract class ModalConfiguration {
|
|||||||
final bool barrierDismissible;
|
final bool barrierDismissible;
|
||||||
|
|
||||||
/// The semantic label used for a dismissible barrier.
|
/// The semantic label used for a dismissible barrier.
|
||||||
final String barrierLabel;
|
final String? barrierLabel;
|
||||||
|
|
||||||
/// The duration of the transition running forwards.
|
/// The duration of the transition running forwards.
|
||||||
final Duration transitionDuration;
|
final Duration transitionDuration;
|
||||||
|
@ -9,7 +9,7 @@ import 'package:flutter/scheduler.dart';
|
|||||||
///
|
///
|
||||||
/// Parameter `returnValue` is the value which will be provided to [OpenContainer.onClosed]
|
/// Parameter `returnValue` is the value which will be provided to [OpenContainer.onClosed]
|
||||||
/// when `action` is called.
|
/// when `action` is called.
|
||||||
typedef CloseContainerActionCallback<S> = void Function({S returnValue});
|
typedef CloseContainerActionCallback<S> = void Function({S? returnValue});
|
||||||
|
|
||||||
/// Signature for a function that creates a [Widget] in open state within an
|
/// Signature for a function that creates a [Widget] in open state within an
|
||||||
/// [OpenContainer].
|
/// [OpenContainer].
|
||||||
@ -74,13 +74,13 @@ typedef ClosedCallback<S> = void Function(S data);
|
|||||||
/// * [Transitions with animated containers](https://material.io/design/motion/choreography.html#transformation)
|
/// * [Transitions with animated containers](https://material.io/design/motion/choreography.html#transformation)
|
||||||
/// in the Material spec.
|
/// in the Material spec.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
class OpenContainer<T extends Object> extends StatefulWidget {
|
class OpenContainer<T extends Object?> extends StatefulWidget {
|
||||||
/// Creates an [OpenContainer].
|
/// Creates an [OpenContainer].
|
||||||
///
|
///
|
||||||
/// All arguments except for [key] must not be null. The arguments
|
/// All arguments except for [key] must not be null. The arguments
|
||||||
/// [openBuilder] and [closedBuilder] are required.
|
/// [openBuilder] and [closedBuilder] are required.
|
||||||
const OpenContainer({
|
const OpenContainer({
|
||||||
Key key,
|
Key? key,
|
||||||
this.closedColor = Colors.white,
|
this.closedColor = Colors.white,
|
||||||
this.openColor = Colors.white,
|
this.openColor = Colors.white,
|
||||||
this.middleColor,
|
this.middleColor,
|
||||||
@ -91,25 +91,14 @@ class OpenContainer<T extends Object> extends StatefulWidget {
|
|||||||
),
|
),
|
||||||
this.openShape = const RoundedRectangleBorder(),
|
this.openShape = const RoundedRectangleBorder(),
|
||||||
this.onClosed,
|
this.onClosed,
|
||||||
@required this.closedBuilder,
|
required this.closedBuilder,
|
||||||
@required this.openBuilder,
|
required this.openBuilder,
|
||||||
this.tappable = true,
|
this.tappable = true,
|
||||||
this.transitionDuration = const Duration(milliseconds: 300),
|
this.transitionDuration = const Duration(milliseconds: 300),
|
||||||
this.transitionType = ContainerTransitionType.fade,
|
this.transitionType = ContainerTransitionType.fade,
|
||||||
this.useRootNavigator = false,
|
this.useRootNavigator = false,
|
||||||
this.routeSettings,
|
this.routeSettings,
|
||||||
}) : assert(closedColor != null),
|
}) : super(key: key);
|
||||||
assert(openColor != null),
|
|
||||||
assert(closedElevation != null),
|
|
||||||
assert(openElevation != null),
|
|
||||||
assert(closedShape != null),
|
|
||||||
assert(openShape != null),
|
|
||||||
assert(closedBuilder != null),
|
|
||||||
assert(openBuilder != null),
|
|
||||||
assert(tappable != null),
|
|
||||||
assert(transitionType != null),
|
|
||||||
assert(useRootNavigator != null),
|
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
/// Background color of the container while it is closed.
|
/// Background color of the container while it is closed.
|
||||||
///
|
///
|
||||||
@ -147,7 +136,7 @@ class OpenContainer<T extends Object> extends StatefulWidget {
|
|||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
/// * [Material.color], which is used to implement this property.
|
/// * [Material.color], which is used to implement this property.
|
||||||
final Color middleColor;
|
final Color? middleColor;
|
||||||
|
|
||||||
/// Elevation of the container while it is closed.
|
/// Elevation of the container while it is closed.
|
||||||
///
|
///
|
||||||
@ -208,7 +197,7 @@ class OpenContainer<T extends Object> extends StatefulWidget {
|
|||||||
///
|
///
|
||||||
/// If no value is returned via [Navigator.pop] or [OpenContainer.openBuilder.action],
|
/// If no value is returned via [Navigator.pop] or [OpenContainer.openBuilder.action],
|
||||||
/// `null` will be returned by default.
|
/// `null` will be returned by default.
|
||||||
final ClosedCallback<T> onClosed;
|
final ClosedCallback<T?>? onClosed;
|
||||||
|
|
||||||
/// Called to obtain the child for the container in the closed state.
|
/// Called to obtain the child for the container in the closed state.
|
||||||
///
|
///
|
||||||
@ -259,13 +248,13 @@ class OpenContainer<T extends Object> extends StatefulWidget {
|
|||||||
final bool useRootNavigator;
|
final bool useRootNavigator;
|
||||||
|
|
||||||
/// Provides additional data to the [openBuilder] route pushed by the Navigator.
|
/// Provides additional data to the [openBuilder] route pushed by the Navigator.
|
||||||
final RouteSettings routeSettings;
|
final RouteSettings? routeSettings;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_OpenContainerState<T> createState() => _OpenContainerState<T>();
|
_OpenContainerState<T> createState() => _OpenContainerState<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _OpenContainerState<T> extends State<OpenContainer<T>> {
|
class _OpenContainerState<T> extends State<OpenContainer<T?>> {
|
||||||
// Key used in [_OpenContainerRoute] to hide the widget returned by
|
// Key used in [_OpenContainerRoute] to hide the widget returned by
|
||||||
// [OpenContainer.openBuilder] in the source route while the container is
|
// [OpenContainer.openBuilder] in the source route while the container is
|
||||||
// opening/open. A copy of that widget is included in the
|
// opening/open. A copy of that widget is included in the
|
||||||
@ -281,7 +270,7 @@ class _OpenContainerState<T> extends State<OpenContainer<T>> {
|
|||||||
Future<void> openContainer() async {
|
Future<void> openContainer() async {
|
||||||
final Color middleColor =
|
final Color middleColor =
|
||||||
widget.middleColor ?? Theme.of(context).canvasColor;
|
widget.middleColor ?? Theme.of(context).canvasColor;
|
||||||
final T data = await Navigator.of(
|
final T? data = await Navigator.of(
|
||||||
context,
|
context,
|
||||||
rootNavigator: widget.useRootNavigator,
|
rootNavigator: widget.useRootNavigator,
|
||||||
).push(_OpenContainerRoute<T>(
|
).push(_OpenContainerRoute<T>(
|
||||||
@ -302,7 +291,7 @@ class _OpenContainerState<T> extends State<OpenContainer<T>> {
|
|||||||
routeSettings: widget.routeSettings,
|
routeSettings: widget.routeSettings,
|
||||||
));
|
));
|
||||||
if (widget.onClosed != null) {
|
if (widget.onClosed != null) {
|
||||||
widget.onClosed(data);
|
widget.onClosed!(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,11 +331,11 @@ class _OpenContainerState<T> extends State<OpenContainer<T>> {
|
|||||||
/// `isVisible` is ignored).
|
/// `isVisible` is ignored).
|
||||||
class _Hideable extends StatefulWidget {
|
class _Hideable extends StatefulWidget {
|
||||||
const _Hideable({
|
const _Hideable({
|
||||||
Key key,
|
Key? key,
|
||||||
this.child,
|
this.child,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final Widget child;
|
final Widget? child;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_Hideable> createState() => _HideableState();
|
State<_Hideable> createState() => _HideableState();
|
||||||
@ -354,9 +343,9 @@ class _Hideable extends StatefulWidget {
|
|||||||
|
|
||||||
class _HideableState extends State<_Hideable> {
|
class _HideableState extends State<_Hideable> {
|
||||||
/// When non-null the child is replaced by a [SizedBox] of the set size.
|
/// When non-null the child is replaced by a [SizedBox] of the set size.
|
||||||
Size get placeholderSize => _placeholderSize;
|
Size? get placeholderSize => _placeholderSize;
|
||||||
Size _placeholderSize;
|
Size? _placeholderSize;
|
||||||
set placeholderSize(Size value) {
|
set placeholderSize(Size? value) {
|
||||||
if (_placeholderSize == value) {
|
if (_placeholderSize == value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -372,7 +361,6 @@ class _HideableState extends State<_Hideable> {
|
|||||||
bool get isVisible => _visible;
|
bool get isVisible => _visible;
|
||||||
bool _visible = true;
|
bool _visible = true;
|
||||||
set isVisible(bool value) {
|
set isVisible(bool value) {
|
||||||
assert(value != null);
|
|
||||||
if (_visible == value) {
|
if (_visible == value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -400,33 +388,22 @@ class _HideableState extends State<_Hideable> {
|
|||||||
|
|
||||||
class _OpenContainerRoute<T> extends ModalRoute<T> {
|
class _OpenContainerRoute<T> extends ModalRoute<T> {
|
||||||
_OpenContainerRoute({
|
_OpenContainerRoute({
|
||||||
@required this.closedColor,
|
required this.closedColor,
|
||||||
@required this.openColor,
|
required this.openColor,
|
||||||
@required this.middleColor,
|
required this.middleColor,
|
||||||
@required double closedElevation,
|
required double closedElevation,
|
||||||
@required this.openElevation,
|
required this.openElevation,
|
||||||
@required ShapeBorder closedShape,
|
required ShapeBorder closedShape,
|
||||||
@required this.openShape,
|
required this.openShape,
|
||||||
@required this.closedBuilder,
|
required this.closedBuilder,
|
||||||
@required this.openBuilder,
|
required this.openBuilder,
|
||||||
@required this.hideableKey,
|
required this.hideableKey,
|
||||||
@required this.closedBuilderKey,
|
required this.closedBuilderKey,
|
||||||
@required this.transitionDuration,
|
required this.transitionDuration,
|
||||||
@required this.transitionType,
|
required this.transitionType,
|
||||||
@required this.useRootNavigator,
|
required this.useRootNavigator,
|
||||||
@required RouteSettings routeSettings,
|
required RouteSettings? routeSettings,
|
||||||
}) : assert(closedColor != null),
|
}) : _elevationTween = Tween<double>(
|
||||||
assert(openColor != null),
|
|
||||||
assert(closedElevation != null),
|
|
||||||
assert(openElevation != null),
|
|
||||||
assert(closedShape != null),
|
|
||||||
assert(openBuilder != null),
|
|
||||||
assert(closedBuilder != null),
|
|
||||||
assert(hideableKey != null),
|
|
||||||
assert(closedBuilderKey != null),
|
|
||||||
assert(transitionType != null),
|
|
||||||
assert(useRootNavigator != null),
|
|
||||||
_elevationTween = Tween<double>(
|
|
||||||
begin: closedElevation,
|
begin: closedElevation,
|
||||||
end: openElevation,
|
end: openElevation,
|
||||||
),
|
),
|
||||||
@ -444,21 +421,21 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
_openOpacityTween = _getOpenOpacityTween(transitionType),
|
_openOpacityTween = _getOpenOpacityTween(transitionType),
|
||||||
super(settings: routeSettings);
|
super(settings: routeSettings);
|
||||||
|
|
||||||
static _FlippableTweenSequence<Color> _getColorTween({
|
static _FlippableTweenSequence<Color?> _getColorTween({
|
||||||
@required ContainerTransitionType transitionType,
|
required ContainerTransitionType transitionType,
|
||||||
@required Color closedColor,
|
required Color closedColor,
|
||||||
@required Color openColor,
|
required Color openColor,
|
||||||
@required Color middleColor,
|
required Color middleColor,
|
||||||
}) {
|
}) {
|
||||||
switch (transitionType) {
|
switch (transitionType) {
|
||||||
case ContainerTransitionType.fade:
|
case ContainerTransitionType.fade:
|
||||||
return _FlippableTweenSequence<Color>(
|
return _FlippableTweenSequence<Color?>(
|
||||||
<TweenSequenceItem<Color>>[
|
<TweenSequenceItem<Color?>>[
|
||||||
TweenSequenceItem<Color>(
|
TweenSequenceItem<Color>(
|
||||||
tween: ConstantTween<Color>(closedColor),
|
tween: ConstantTween<Color>(closedColor),
|
||||||
weight: 1 / 5,
|
weight: 1 / 5,
|
||||||
),
|
),
|
||||||
TweenSequenceItem<Color>(
|
TweenSequenceItem<Color?>(
|
||||||
tween: ColorTween(begin: closedColor, end: openColor),
|
tween: ColorTween(begin: closedColor, end: openColor),
|
||||||
weight: 1 / 5,
|
weight: 1 / 5,
|
||||||
),
|
),
|
||||||
@ -469,20 +446,19 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
case ContainerTransitionType.fadeThrough:
|
case ContainerTransitionType.fadeThrough:
|
||||||
return _FlippableTweenSequence<Color>(
|
return _FlippableTweenSequence<Color?>(
|
||||||
<TweenSequenceItem<Color>>[
|
<TweenSequenceItem<Color?>>[
|
||||||
TweenSequenceItem<Color>(
|
TweenSequenceItem<Color?>(
|
||||||
tween: ColorTween(begin: closedColor, end: middleColor),
|
tween: ColorTween(begin: closedColor, end: middleColor),
|
||||||
weight: 1 / 5,
|
weight: 1 / 5,
|
||||||
),
|
),
|
||||||
TweenSequenceItem<Color>(
|
TweenSequenceItem<Color?>(
|
||||||
tween: ColorTween(begin: middleColor, end: openColor),
|
tween: ColorTween(begin: middleColor, end: openColor),
|
||||||
weight: 4 / 5,
|
weight: 4 / 5,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null; // unreachable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static _FlippableTweenSequence<double> _getClosedOpacityTween(
|
static _FlippableTweenSequence<double> _getClosedOpacityTween(
|
||||||
@ -497,7 +473,6 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
case ContainerTransitionType.fadeThrough:
|
case ContainerTransitionType.fadeThrough:
|
||||||
return _FlippableTweenSequence<double>(
|
return _FlippableTweenSequence<double>(
|
||||||
<TweenSequenceItem<double>>[
|
<TweenSequenceItem<double>>[
|
||||||
@ -511,9 +486,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return null; // unreachable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static _FlippableTweenSequence<double> _getOpenOpacityTween(
|
static _FlippableTweenSequence<double> _getOpenOpacityTween(
|
||||||
@ -536,7 +509,6 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
case ContainerTransitionType.fadeThrough:
|
case ContainerTransitionType.fadeThrough:
|
||||||
return _FlippableTweenSequence<double>(
|
return _FlippableTweenSequence<double>(
|
||||||
<TweenSequenceItem<double>>[
|
<TweenSequenceItem<double>>[
|
||||||
@ -550,9 +522,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return null; // unreachable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Color closedColor;
|
final Color closedColor;
|
||||||
@ -579,11 +549,11 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
final ShapeBorderTween _shapeTween;
|
final ShapeBorderTween _shapeTween;
|
||||||
final _FlippableTweenSequence<double> _closedOpacityTween;
|
final _FlippableTweenSequence<double> _closedOpacityTween;
|
||||||
final _FlippableTweenSequence<double> _openOpacityTween;
|
final _FlippableTweenSequence<double> _openOpacityTween;
|
||||||
final _FlippableTweenSequence<Color> _colorTween;
|
final _FlippableTweenSequence<Color?> _colorTween;
|
||||||
|
|
||||||
static final TweenSequence<Color> _scrimFadeInTween = TweenSequence<Color>(
|
static final TweenSequence<Color?> _scrimFadeInTween = TweenSequence<Color?>(
|
||||||
<TweenSequenceItem<Color>>[
|
<TweenSequenceItem<Color?>>[
|
||||||
TweenSequenceItem<Color>(
|
TweenSequenceItem<Color?>(
|
||||||
tween: ColorTween(begin: Colors.transparent, end: Colors.black54),
|
tween: ColorTween(begin: Colors.transparent, end: Colors.black54),
|
||||||
weight: 1 / 5,
|
weight: 1 / 5,
|
||||||
),
|
),
|
||||||
@ -593,7 +563,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
static final Tween<Color> _scrimFadeOutTween = ColorTween(
|
static final Tween<Color?> _scrimFadeOutTween = ColorTween(
|
||||||
begin: Colors.transparent,
|
begin: Colors.transparent,
|
||||||
end: Colors.black54,
|
end: Colors.black54,
|
||||||
);
|
);
|
||||||
@ -608,14 +578,14 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
// the bounds of the enclosing [Navigator].
|
// the bounds of the enclosing [Navigator].
|
||||||
final RectTween _rectTween = RectTween();
|
final RectTween _rectTween = RectTween();
|
||||||
|
|
||||||
AnimationStatus _lastAnimationStatus;
|
AnimationStatus? _lastAnimationStatus;
|
||||||
AnimationStatus _currentAnimationStatus;
|
AnimationStatus? _currentAnimationStatus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TickerFuture didPush() {
|
TickerFuture didPush() {
|
||||||
_takeMeasurements(navigatorContext: hideableKey.currentContext);
|
_takeMeasurements(navigatorContext: hideableKey.currentContext!);
|
||||||
|
|
||||||
animation.addStatusListener((AnimationStatus status) {
|
animation!.addStatusListener((AnimationStatus status) {
|
||||||
_lastAnimationStatus = _currentAnimationStatus;
|
_lastAnimationStatus = _currentAnimationStatus;
|
||||||
_currentAnimationStatus = status;
|
_currentAnimationStatus = status;
|
||||||
switch (status) {
|
switch (status) {
|
||||||
@ -635,9 +605,9 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool didPop(T result) {
|
bool didPop(T? result) {
|
||||||
_takeMeasurements(
|
_takeMeasurements(
|
||||||
navigatorContext: subtreeContext,
|
navigatorContext: subtreeContext!,
|
||||||
delayForSourceRoute: true,
|
delayForSourceRoute: true,
|
||||||
);
|
);
|
||||||
return super.didPop(result);
|
return super.didPop(result);
|
||||||
@ -645,44 +615,44 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
if (hideableKey?.currentState?.isVisible == false) {
|
if (hideableKey.currentState?.isVisible == false) {
|
||||||
// This route may be disposed without dismissing its animation if it is
|
// This route may be disposed without dismissing its animation if it is
|
||||||
// removed by the navigator.
|
// removed by the navigator.
|
||||||
SchedulerBinding.instance
|
SchedulerBinding.instance!
|
||||||
.addPostFrameCallback((Duration d) => _toggleHideable(hide: false));
|
.addPostFrameCallback((Duration d) => _toggleHideable(hide: false));
|
||||||
}
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _toggleHideable({bool hide}) {
|
void _toggleHideable({required bool hide}) {
|
||||||
if (hideableKey?.currentState != null) {
|
if (hideableKey.currentState != null) {
|
||||||
hideableKey.currentState
|
hideableKey.currentState!
|
||||||
..placeholderSize = null
|
..placeholderSize = null
|
||||||
..isVisible = !hide;
|
..isVisible = !hide;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _takeMeasurements({
|
void _takeMeasurements({
|
||||||
BuildContext navigatorContext,
|
required BuildContext navigatorContext,
|
||||||
bool delayForSourceRoute = false,
|
bool delayForSourceRoute = false,
|
||||||
}) {
|
}) {
|
||||||
final RenderBox navigator = Navigator.of(
|
final RenderBox navigator = Navigator.of(
|
||||||
navigatorContext,
|
navigatorContext,
|
||||||
rootNavigator: useRootNavigator,
|
rootNavigator: useRootNavigator,
|
||||||
).context.findRenderObject();
|
).context.findRenderObject() as RenderBox;
|
||||||
final Size navSize = _getSize(navigator);
|
final Size navSize = _getSize(navigator);
|
||||||
_rectTween.end = Offset.zero & navSize;
|
_rectTween.end = Offset.zero & navSize;
|
||||||
|
|
||||||
void takeMeasurementsInSourceRoute([Duration _]) {
|
void takeMeasurementsInSourceRoute([Duration? _]) {
|
||||||
if (!navigator.attached || hideableKey.currentContext == null) {
|
if (!navigator.attached || hideableKey.currentContext == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_rectTween.begin = _getRect(hideableKey, navigator);
|
_rectTween.begin = _getRect(hideableKey, navigator);
|
||||||
hideableKey.currentState.placeholderSize = _rectTween.begin.size;
|
hideableKey.currentState!.placeholderSize = _rectTween.begin!.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delayForSourceRoute) {
|
if (delayForSourceRoute) {
|
||||||
SchedulerBinding.instance
|
SchedulerBinding.instance!
|
||||||
.addPostFrameCallback(takeMeasurementsInSourceRoute);
|
.addPostFrameCallback(takeMeasurementsInSourceRoute);
|
||||||
} else {
|
} else {
|
||||||
takeMeasurementsInSourceRoute();
|
takeMeasurementsInSourceRoute();
|
||||||
@ -690,7 +660,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Size _getSize(RenderBox render) {
|
Size _getSize(RenderBox render) {
|
||||||
assert(render != null && render.hasSize);
|
assert(render.hasSize);
|
||||||
return render.size;
|
return render.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,9 +668,10 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
// coordinate system of `ancestor`.
|
// coordinate system of `ancestor`.
|
||||||
Rect _getRect(GlobalKey key, RenderBox ancestor) {
|
Rect _getRect(GlobalKey key, RenderBox ancestor) {
|
||||||
assert(key.currentContext != null);
|
assert(key.currentContext != null);
|
||||||
assert(ancestor != null && ancestor.hasSize);
|
assert(ancestor.hasSize);
|
||||||
final RenderBox render = key.currentContext.findRenderObject();
|
final RenderBox render =
|
||||||
assert(render != null && render.hasSize);
|
key.currentContext!.findRenderObject() as RenderBox;
|
||||||
|
assert(render.hasSize);
|
||||||
return MatrixUtils.transformRect(
|
return MatrixUtils.transformRect(
|
||||||
render.getTransformTo(ancestor),
|
render.getTransformTo(ancestor),
|
||||||
Offset.zero & render.size,
|
Offset.zero & render.size,
|
||||||
@ -720,6 +691,8 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
case AnimationStatus.reverse:
|
case AnimationStatus.reverse:
|
||||||
isInProgress = true;
|
isInProgress = true;
|
||||||
break;
|
break;
|
||||||
|
case null:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
switch (_lastAnimationStatus) {
|
switch (_lastAnimationStatus) {
|
||||||
case AnimationStatus.completed:
|
case AnimationStatus.completed:
|
||||||
@ -730,12 +703,14 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
case AnimationStatus.reverse:
|
case AnimationStatus.reverse:
|
||||||
wasInProgress = true;
|
wasInProgress = true;
|
||||||
break;
|
break;
|
||||||
|
case null:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return wasInProgress && isInProgress;
|
return wasInProgress && isInProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
void closeContainer({T returnValue}) {
|
void closeContainer({T? returnValue}) {
|
||||||
Navigator.of(subtreeContext).pop(returnValue);
|
Navigator.of(subtreeContext!).pop(returnValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -748,7 +723,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
child: AnimatedBuilder(
|
child: AnimatedBuilder(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
builder: (BuildContext context, Widget child) {
|
builder: (BuildContext context, Widget? child) {
|
||||||
if (animation.isCompleted) {
|
if (animation.isCompleted) {
|
||||||
return SizedBox.expand(
|
return SizedBox.expand(
|
||||||
child: Material(
|
child: Material(
|
||||||
@ -771,9 +746,9 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
reverseCurve:
|
reverseCurve:
|
||||||
_transitionWasInterrupted ? null : Curves.fastOutSlowIn.flipped,
|
_transitionWasInterrupted ? null : Curves.fastOutSlowIn.flipped,
|
||||||
);
|
);
|
||||||
TweenSequence<Color> colorTween;
|
TweenSequence<Color?>? colorTween;
|
||||||
TweenSequence<double> closedOpacityTween, openOpacityTween;
|
TweenSequence<double>? closedOpacityTween, openOpacityTween;
|
||||||
Animatable<Color> scrimTween;
|
Animatable<Color?>? scrimTween;
|
||||||
switch (animation.status) {
|
switch (animation.status) {
|
||||||
case AnimationStatus.dismissed:
|
case AnimationStatus.dismissed:
|
||||||
case AnimationStatus.forward:
|
case AnimationStatus.forward:
|
||||||
@ -804,10 +779,10 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
assert(openOpacityTween != null);
|
assert(openOpacityTween != null);
|
||||||
assert(scrimTween != null);
|
assert(scrimTween != null);
|
||||||
|
|
||||||
final Rect rect = _rectTween.evaluate(curvedAnimation);
|
final Rect rect = _rectTween.evaluate(curvedAnimation)!;
|
||||||
return SizedBox.expand(
|
return SizedBox.expand(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: scrimTween.evaluate(curvedAnimation),
|
color: scrimTween!.evaluate(curvedAnimation),
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
child: Transform.translate(
|
child: Transform.translate(
|
||||||
@ -818,7 +793,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
child: Material(
|
child: Material(
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
animationDuration: Duration.zero,
|
animationDuration: Duration.zero,
|
||||||
color: colorTween.evaluate(animation),
|
color: colorTween!.evaluate(animation),
|
||||||
shape: _shapeTween.evaluate(curvedAnimation),
|
shape: _shapeTween.evaluate(curvedAnimation),
|
||||||
elevation: _elevationTween.evaluate(curvedAnimation),
|
elevation: _elevationTween.evaluate(curvedAnimation),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
@ -829,13 +804,13 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
fit: BoxFit.fitWidth,
|
fit: BoxFit.fitWidth,
|
||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: _rectTween.begin.width,
|
width: _rectTween.begin!.width,
|
||||||
height: _rectTween.begin.height,
|
height: _rectTween.begin!.height,
|
||||||
child: (hideableKey.currentState?.isInTree ??
|
child: (hideableKey.currentState?.isInTree ??
|
||||||
false)
|
false)
|
||||||
? null
|
? null
|
||||||
: Opacity(
|
: Opacity(
|
||||||
opacity: closedOpacityTween
|
opacity: closedOpacityTween!
|
||||||
.evaluate(animation),
|
.evaluate(animation),
|
||||||
child: Builder(
|
child: Builder(
|
||||||
key: closedBuilderKey,
|
key: closedBuilderKey,
|
||||||
@ -854,10 +829,10 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
fit: BoxFit.fitWidth,
|
fit: BoxFit.fitWidth,
|
||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: _rectTween.end.width,
|
width: _rectTween.end!.width,
|
||||||
height: _rectTween.end.height,
|
height: _rectTween.end!.height,
|
||||||
child: Opacity(
|
child: Opacity(
|
||||||
opacity: openOpacityTween.evaluate(animation),
|
opacity: openOpacityTween!.evaluate(animation),
|
||||||
child: Builder(
|
child: Builder(
|
||||||
key: _openBuilderKey,
|
key: _openBuilderKey,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
@ -884,7 +859,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
bool get maintainState => true;
|
bool get maintainState => true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color get barrierColor => null;
|
Color? get barrierColor => null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get opaque => true;
|
bool get opaque => true;
|
||||||
@ -893,16 +868,16 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
|
|||||||
bool get barrierDismissible => false;
|
bool get barrierDismissible => false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get barrierLabel => null;
|
String? get barrierLabel => null;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FlippableTweenSequence<T> extends TweenSequence<T> {
|
class _FlippableTweenSequence<T> extends TweenSequence<T> {
|
||||||
_FlippableTweenSequence(this._items) : super(_items);
|
_FlippableTweenSequence(this._items) : super(_items);
|
||||||
|
|
||||||
final List<TweenSequenceItem<T>> _items;
|
final List<TweenSequenceItem<T>> _items;
|
||||||
_FlippableTweenSequence<T> _flipped;
|
_FlippableTweenSequence<T>? _flipped;
|
||||||
|
|
||||||
_FlippableTweenSequence<T> get flipped {
|
_FlippableTweenSequence<T>? get flipped {
|
||||||
if (_flipped == null) {
|
if (_flipped == null) {
|
||||||
final List<TweenSequenceItem<T>> newItems = <TweenSequenceItem<T>>[];
|
final List<TweenSequenceItem<T>> newItems = <TweenSequenceItem<T>>[];
|
||||||
for (int i = 0; i < _items.length; i++) {
|
for (int i = 0; i < _items.length; i++) {
|
||||||
|
@ -18,14 +18,11 @@ class _ChildEntry {
|
|||||||
/// The [primaryController], [secondaryController], [transition] and
|
/// The [primaryController], [secondaryController], [transition] and
|
||||||
/// [widgetChild] parameters must not be null.
|
/// [widgetChild] parameters must not be null.
|
||||||
_ChildEntry({
|
_ChildEntry({
|
||||||
@required this.primaryController,
|
required this.primaryController,
|
||||||
@required this.secondaryController,
|
required this.secondaryController,
|
||||||
@required this.transition,
|
required this.transition,
|
||||||
@required this.widgetChild,
|
required this.widgetChild,
|
||||||
}) : assert(primaryController != null),
|
});
|
||||||
assert(secondaryController != null),
|
|
||||||
assert(widgetChild != null),
|
|
||||||
assert(transition != null);
|
|
||||||
|
|
||||||
/// The animation controller for the child's transition.
|
/// The animation controller for the child's transition.
|
||||||
final AnimationController primaryController;
|
final AnimationController primaryController;
|
||||||
@ -172,17 +169,13 @@ class PageTransitionSwitcher extends StatefulWidget {
|
|||||||
/// The [duration], [reverse], and [transitionBuilder] parameters
|
/// The [duration], [reverse], and [transitionBuilder] parameters
|
||||||
/// must not be null.
|
/// must not be null.
|
||||||
const PageTransitionSwitcher({
|
const PageTransitionSwitcher({
|
||||||
Key key,
|
Key? key,
|
||||||
this.duration = const Duration(milliseconds: 300),
|
this.duration = const Duration(milliseconds: 300),
|
||||||
this.reverse = false,
|
this.reverse = false,
|
||||||
@required this.transitionBuilder,
|
required this.transitionBuilder,
|
||||||
this.layoutBuilder = defaultLayoutBuilder,
|
this.layoutBuilder = defaultLayoutBuilder,
|
||||||
this.child,
|
this.child,
|
||||||
}) : assert(duration != null),
|
}) : super(key: key);
|
||||||
assert(reverse != null),
|
|
||||||
assert(transitionBuilder != null),
|
|
||||||
assert(layoutBuilder != null),
|
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
/// The current child widget to display.
|
/// The current child widget to display.
|
||||||
///
|
///
|
||||||
@ -195,7 +188,7 @@ class PageTransitionSwitcher extends StatefulWidget {
|
|||||||
///
|
///
|
||||||
/// The child is considered to be "new" if it has a different type or [Key]
|
/// The child is considered to be "new" if it has a different type or [Key]
|
||||||
/// (see [Widget.canUpdate]).
|
/// (see [Widget.canUpdate]).
|
||||||
final Widget child;
|
final Widget? child;
|
||||||
|
|
||||||
/// The duration of the transition from the old [child] value to the new one.
|
/// The duration of the transition from the old [child] value to the new one.
|
||||||
///
|
///
|
||||||
@ -285,7 +278,7 @@ class PageTransitionSwitcher extends StatefulWidget {
|
|||||||
class _PageTransitionSwitcherState extends State<PageTransitionSwitcher>
|
class _PageTransitionSwitcherState extends State<PageTransitionSwitcher>
|
||||||
with TickerProviderStateMixin {
|
with TickerProviderStateMixin {
|
||||||
final List<_ChildEntry> _activeEntries = <_ChildEntry>[];
|
final List<_ChildEntry> _activeEntries = <_ChildEntry>[];
|
||||||
_ChildEntry _currentEntry;
|
_ChildEntry? _currentEntry;
|
||||||
int _childNumber = 0;
|
int _childNumber = 0;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -308,30 +301,30 @@ class _PageTransitionSwitcherState extends State<PageTransitionSwitcher>
|
|||||||
final bool hasOldChild = _currentEntry != null;
|
final bool hasOldChild = _currentEntry != null;
|
||||||
if (hasNewChild != hasOldChild ||
|
if (hasNewChild != hasOldChild ||
|
||||||
hasNewChild &&
|
hasNewChild &&
|
||||||
!Widget.canUpdate(widget.child, _currentEntry.widgetChild)) {
|
!Widget.canUpdate(widget.child!, _currentEntry!.widgetChild)) {
|
||||||
// Child has changed, fade current entry out and add new entry.
|
// Child has changed, fade current entry out and add new entry.
|
||||||
_childNumber += 1;
|
_childNumber += 1;
|
||||||
_addEntryForNewChild(shouldAnimate: true);
|
_addEntryForNewChild(shouldAnimate: true);
|
||||||
} else if (_currentEntry != null) {
|
} else if (_currentEntry != null) {
|
||||||
assert(hasOldChild && hasNewChild);
|
assert(hasOldChild && hasNewChild);
|
||||||
assert(Widget.canUpdate(widget.child, _currentEntry.widgetChild));
|
assert(Widget.canUpdate(widget.child!, _currentEntry!.widgetChild));
|
||||||
// Child has been updated. Make sure we update the child widget and
|
// Child has been updated. Make sure we update the child widget and
|
||||||
// transition in _currentEntry even though we're not going to start a new
|
// transition in _currentEntry even though we're not going to start a new
|
||||||
// animation, but keep the key from the old transition so that we
|
// animation, but keep the key from the old transition so that we
|
||||||
// update the transition instead of replacing it.
|
// update the transition instead of replacing it.
|
||||||
_currentEntry.widgetChild = widget.child;
|
_currentEntry!.widgetChild = widget.child!;
|
||||||
_updateTransitionForEntry(_currentEntry); // uses entry.widgetChild
|
_updateTransitionForEntry(_currentEntry!); // uses entry.widgetChild
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _addEntryForNewChild({@required bool shouldAnimate}) {
|
void _addEntryForNewChild({required bool shouldAnimate}) {
|
||||||
assert(shouldAnimate || _currentEntry == null);
|
assert(shouldAnimate || _currentEntry == null);
|
||||||
if (_currentEntry != null) {
|
if (_currentEntry != null) {
|
||||||
assert(shouldAnimate);
|
assert(shouldAnimate);
|
||||||
if (widget.reverse) {
|
if (widget.reverse) {
|
||||||
_currentEntry.primaryController.reverse();
|
_currentEntry!.primaryController.reverse();
|
||||||
} else {
|
} else {
|
||||||
_currentEntry.secondaryController.forward();
|
_currentEntry!.secondaryController.forward();
|
||||||
}
|
}
|
||||||
_currentEntry = null;
|
_currentEntry = null;
|
||||||
}
|
}
|
||||||
@ -359,35 +352,31 @@ class _PageTransitionSwitcherState extends State<PageTransitionSwitcher>
|
|||||||
primaryController.value = 1.0;
|
primaryController.value = 1.0;
|
||||||
}
|
}
|
||||||
_currentEntry = _newEntry(
|
_currentEntry = _newEntry(
|
||||||
child: widget.child,
|
child: widget.child!,
|
||||||
primaryController: primaryController,
|
primaryController: primaryController,
|
||||||
secondaryController: secondaryController,
|
secondaryController: secondaryController,
|
||||||
builder: widget.transitionBuilder,
|
builder: widget.transitionBuilder,
|
||||||
);
|
);
|
||||||
if (widget.reverse && _activeEntries.isNotEmpty) {
|
if (widget.reverse && _activeEntries.isNotEmpty) {
|
||||||
// Add below old child.
|
// Add below old child.
|
||||||
_activeEntries.insert(_activeEntries.length - 1, _currentEntry);
|
_activeEntries.insert(_activeEntries.length - 1, _currentEntry!);
|
||||||
} else {
|
} else {
|
||||||
// Add on top of old child.
|
// Add on top of old child.
|
||||||
_activeEntries.add(_currentEntry);
|
_activeEntries.add(_currentEntry!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ChildEntry _newEntry({
|
_ChildEntry _newEntry({
|
||||||
@required Widget child,
|
required Widget child,
|
||||||
@required PageTransitionSwitcherTransitionBuilder builder,
|
required PageTransitionSwitcherTransitionBuilder builder,
|
||||||
@required AnimationController primaryController,
|
required AnimationController primaryController,
|
||||||
@required AnimationController secondaryController,
|
required AnimationController secondaryController,
|
||||||
}) {
|
}) {
|
||||||
final Widget transition = builder(
|
final Widget transition = builder(
|
||||||
child,
|
child,
|
||||||
primaryController,
|
primaryController,
|
||||||
secondaryController,
|
secondaryController,
|
||||||
);
|
);
|
||||||
assert(
|
|
||||||
transition != null,
|
|
||||||
'PageTransitionSwitcher.builder must not return null.',
|
|
||||||
);
|
|
||||||
final _ChildEntry entry = _ChildEntry(
|
final _ChildEntry entry = _ChildEntry(
|
||||||
widgetChild: child,
|
widgetChild: child,
|
||||||
transition: KeyedSubtree.wrap(
|
transition: KeyedSubtree.wrap(
|
||||||
@ -426,10 +415,6 @@ class _PageTransitionSwitcherState extends State<PageTransitionSwitcher>
|
|||||||
entry.primaryController,
|
entry.primaryController,
|
||||||
entry.secondaryController,
|
entry.secondaryController,
|
||||||
);
|
);
|
||||||
assert(
|
|
||||||
transition != null,
|
|
||||||
'PageTransitionSwitcher.builder must not return null.',
|
|
||||||
);
|
|
||||||
entry.transition = KeyedSubtree(
|
entry.transition = KeyedSubtree(
|
||||||
key: entry.transition.key,
|
key: entry.transition.key,
|
||||||
child: transition,
|
child: transition,
|
||||||
|
@ -4,19 +4,9 @@
|
|||||||
|
|
||||||
import 'package:flutter/animation.dart';
|
import 'package:flutter/animation.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart'
|
import 'package:flutter/material.dart';
|
||||||
hide
|
|
||||||
decelerateEasing, // ignore: undefined_hidden_name
|
|
||||||
standardEasing, // ignore: undefined_hidden_name
|
|
||||||
accelerateEasing; // ignore: undefined_hidden_name
|
|
||||||
// TODO(goderbauer): Remove implementation import when material properly exports the file.
|
|
||||||
import 'package:flutter/src/material/curves.dart'; // ignore: implementation_imports
|
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
// TODO(shihaohong): Remove DualTransitionBuilder once flutter/flutter's `stable`
|
|
||||||
// branch contains DualTransitionBuilder.
|
|
||||||
import 'dual_transition_builder.dart' as dual_transition_builder;
|
|
||||||
|
|
||||||
/// Determines which type of shared axis transition is used.
|
/// Determines which type of shared axis transition is used.
|
||||||
enum SharedAxisTransitionType {
|
enum SharedAxisTransitionType {
|
||||||
/// Creates a shared axis vertical (y-axis) page transition.
|
/// Creates a shared axis vertical (y-axis) page transition.
|
||||||
@ -87,9 +77,9 @@ enum SharedAxisTransitionType {
|
|||||||
class SharedAxisPageTransitionsBuilder extends PageTransitionsBuilder {
|
class SharedAxisPageTransitionsBuilder extends PageTransitionsBuilder {
|
||||||
/// Construct a [SharedAxisPageTransitionsBuilder].
|
/// Construct a [SharedAxisPageTransitionsBuilder].
|
||||||
const SharedAxisPageTransitionsBuilder({
|
const SharedAxisPageTransitionsBuilder({
|
||||||
@required this.transitionType,
|
required this.transitionType,
|
||||||
this.fillColor,
|
this.fillColor,
|
||||||
}) : assert(transitionType != null);
|
});
|
||||||
|
|
||||||
/// Determines which [SharedAxisTransitionType] to build.
|
/// Determines which [SharedAxisTransitionType] to build.
|
||||||
final SharedAxisTransitionType transitionType;
|
final SharedAxisTransitionType transitionType;
|
||||||
@ -97,12 +87,12 @@ class SharedAxisPageTransitionsBuilder extends PageTransitionsBuilder {
|
|||||||
/// The color to use for the background color during the transition.
|
/// The color to use for the background color during the transition.
|
||||||
///
|
///
|
||||||
/// This defaults to the [Theme]'s [ThemeData.canvasColor].
|
/// This defaults to the [Theme]'s [ThemeData.canvasColor].
|
||||||
final Color fillColor;
|
final Color? fillColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildTransitions<T>(
|
Widget buildTransitions<T>(
|
||||||
PageRoute<T> route,
|
PageRoute<T>? route,
|
||||||
BuildContext context,
|
BuildContext? context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Animation<double> secondaryAnimation,
|
Animation<double> secondaryAnimation,
|
||||||
Widget child,
|
Widget child,
|
||||||
@ -197,14 +187,13 @@ class SharedAxisTransition extends StatelessWidget {
|
|||||||
/// The [animation] and [secondaryAnimation] argument are required and must
|
/// The [animation] and [secondaryAnimation] argument are required and must
|
||||||
/// not be null.
|
/// not be null.
|
||||||
const SharedAxisTransition({
|
const SharedAxisTransition({
|
||||||
Key key,
|
Key? key,
|
||||||
@required this.animation,
|
required this.animation,
|
||||||
@required this.secondaryAnimation,
|
required this.secondaryAnimation,
|
||||||
@required this.transitionType,
|
required this.transitionType,
|
||||||
this.fillColor,
|
this.fillColor,
|
||||||
this.child,
|
this.child,
|
||||||
}) : assert(transitionType != null),
|
}) : super(key: key);
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
/// The animation that drives the [child]'s entrance and exit.
|
/// The animation that drives the [child]'s entrance and exit.
|
||||||
///
|
///
|
||||||
@ -234,23 +223,23 @@ class SharedAxisTransition extends StatelessWidget {
|
|||||||
/// The color to use for the background color during the transition.
|
/// The color to use for the background color during the transition.
|
||||||
///
|
///
|
||||||
/// This defaults to the [Theme]'s [ThemeData.canvasColor].
|
/// This defaults to the [Theme]'s [ThemeData.canvasColor].
|
||||||
final Color fillColor;
|
final Color? fillColor;
|
||||||
|
|
||||||
/// The widget below this widget in the tree.
|
/// The widget below this widget in the tree.
|
||||||
///
|
///
|
||||||
/// This widget will transition in and out as driven by [animation] and
|
/// This widget will transition in and out as driven by [animation] and
|
||||||
/// [secondaryAnimation].
|
/// [secondaryAnimation].
|
||||||
final Widget child;
|
final Widget? child;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final Color color = fillColor ?? Theme.of(context).canvasColor;
|
final Color color = fillColor ?? Theme.of(context).canvasColor;
|
||||||
return dual_transition_builder.DualTransitionBuilder(
|
return DualTransitionBuilder(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
forwardBuilder: (
|
forwardBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return _EnterTransition(
|
return _EnterTransition(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
@ -261,7 +250,7 @@ class SharedAxisTransition extends StatelessWidget {
|
|||||||
reverseBuilder: (
|
reverseBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return _ExitTransition(
|
return _ExitTransition(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
@ -271,12 +260,12 @@ class SharedAxisTransition extends StatelessWidget {
|
|||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: dual_transition_builder.DualTransitionBuilder(
|
child: DualTransitionBuilder(
|
||||||
animation: ReverseAnimation(secondaryAnimation),
|
animation: ReverseAnimation(secondaryAnimation),
|
||||||
forwardBuilder: (
|
forwardBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return _EnterTransition(
|
return _EnterTransition(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
@ -288,7 +277,7 @@ class SharedAxisTransition extends StatelessWidget {
|
|||||||
reverseBuilder: (
|
reverseBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return _ExitTransition(
|
return _ExitTransition(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
@ -305,15 +294,15 @@ class SharedAxisTransition extends StatelessWidget {
|
|||||||
|
|
||||||
class _EnterTransition extends StatelessWidget {
|
class _EnterTransition extends StatelessWidget {
|
||||||
const _EnterTransition({
|
const _EnterTransition({
|
||||||
this.animation,
|
required this.animation,
|
||||||
this.transitionType,
|
required this.transitionType,
|
||||||
this.reverse = false,
|
this.reverse = false,
|
||||||
this.child,
|
this.child,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Animation<double> animation;
|
final Animation<double> animation;
|
||||||
final SharedAxisTransitionType transitionType;
|
final SharedAxisTransitionType transitionType;
|
||||||
final Widget child;
|
final Widget? child;
|
||||||
final bool reverse;
|
final bool reverse;
|
||||||
|
|
||||||
static final Animatable<double> _fadeInTransition = CurveTween(
|
static final Animatable<double> _fadeInTransition = CurveTween(
|
||||||
@ -343,7 +332,7 @@ class _EnterTransition extends StatelessWidget {
|
|||||||
opacity: _fadeInTransition.animate(animation),
|
opacity: _fadeInTransition.animate(animation),
|
||||||
child: AnimatedBuilder(
|
child: AnimatedBuilder(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
builder: (BuildContext context, Widget child) {
|
builder: (BuildContext context, Widget? child) {
|
||||||
return Transform.translate(
|
return Transform.translate(
|
||||||
offset: slideInTransition.evaluate(animation),
|
offset: slideInTransition.evaluate(animation),
|
||||||
child: child,
|
child: child,
|
||||||
@ -352,7 +341,6 @@ class _EnterTransition extends StatelessWidget {
|
|||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
case SharedAxisTransitionType.vertical:
|
case SharedAxisTransitionType.vertical:
|
||||||
final Animatable<Offset> slideInTransition = Tween<Offset>(
|
final Animatable<Offset> slideInTransition = Tween<Offset>(
|
||||||
begin: Offset(0.0, !reverse ? 30.0 : -30.0),
|
begin: Offset(0.0, !reverse ? 30.0 : -30.0),
|
||||||
@ -363,7 +351,7 @@ class _EnterTransition extends StatelessWidget {
|
|||||||
opacity: _fadeInTransition.animate(animation),
|
opacity: _fadeInTransition.animate(animation),
|
||||||
child: AnimatedBuilder(
|
child: AnimatedBuilder(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
builder: (BuildContext context, Widget child) {
|
builder: (BuildContext context, Widget? child) {
|
||||||
return Transform.translate(
|
return Transform.translate(
|
||||||
offset: slideInTransition.evaluate(animation),
|
offset: slideInTransition.evaluate(animation),
|
||||||
child: child,
|
child: child,
|
||||||
@ -372,7 +360,6 @@ class _EnterTransition extends StatelessWidget {
|
|||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
case SharedAxisTransitionType.scaled:
|
case SharedAxisTransitionType.scaled:
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
opacity: _fadeInTransition.animate(animation),
|
opacity: _fadeInTransition.animate(animation),
|
||||||
@ -382,18 +369,16 @@ class _EnterTransition extends StatelessWidget {
|
|||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return null; // unreachable
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ExitTransition extends StatelessWidget {
|
class _ExitTransition extends StatelessWidget {
|
||||||
const _ExitTransition({
|
const _ExitTransition({
|
||||||
this.animation,
|
required this.animation,
|
||||||
this.transitionType,
|
required this.transitionType,
|
||||||
this.reverse = false,
|
this.reverse = false,
|
||||||
@required this.fillColor,
|
required this.fillColor,
|
||||||
this.child,
|
this.child,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -401,7 +386,7 @@ class _ExitTransition extends StatelessWidget {
|
|||||||
final SharedAxisTransitionType transitionType;
|
final SharedAxisTransitionType transitionType;
|
||||||
final bool reverse;
|
final bool reverse;
|
||||||
final Color fillColor;
|
final Color fillColor;
|
||||||
final Widget child;
|
final Widget? child;
|
||||||
|
|
||||||
static final Animatable<double> _fadeOutTransition = _FlippedCurveTween(
|
static final Animatable<double> _fadeOutTransition = _FlippedCurveTween(
|
||||||
curve: accelerateEasing,
|
curve: accelerateEasing,
|
||||||
@ -432,7 +417,7 @@ class _ExitTransition extends StatelessWidget {
|
|||||||
color: fillColor,
|
color: fillColor,
|
||||||
child: AnimatedBuilder(
|
child: AnimatedBuilder(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
builder: (BuildContext context, Widget child) {
|
builder: (BuildContext context, Widget? child) {
|
||||||
return Transform.translate(
|
return Transform.translate(
|
||||||
offset: slideOutTransition.evaluate(animation),
|
offset: slideOutTransition.evaluate(animation),
|
||||||
child: child,
|
child: child,
|
||||||
@ -442,7 +427,6 @@ class _ExitTransition extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
case SharedAxisTransitionType.vertical:
|
case SharedAxisTransitionType.vertical:
|
||||||
final Animatable<Offset> slideOutTransition = Tween<Offset>(
|
final Animatable<Offset> slideOutTransition = Tween<Offset>(
|
||||||
begin: Offset.zero,
|
begin: Offset.zero,
|
||||||
@ -455,7 +439,7 @@ class _ExitTransition extends StatelessWidget {
|
|||||||
color: fillColor,
|
color: fillColor,
|
||||||
child: AnimatedBuilder(
|
child: AnimatedBuilder(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
builder: (BuildContext context, Widget child) {
|
builder: (BuildContext context, Widget? child) {
|
||||||
return Transform.translate(
|
return Transform.translate(
|
||||||
offset: slideOutTransition.evaluate(animation),
|
offset: slideOutTransition.evaluate(animation),
|
||||||
child: child,
|
child: child,
|
||||||
@ -465,7 +449,6 @@ class _ExitTransition extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
case SharedAxisTransitionType.scaled:
|
case SharedAxisTransitionType.scaled:
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
opacity: _fadeOutTransition.animate(animation),
|
opacity: _fadeOutTransition.animate(animation),
|
||||||
@ -478,9 +461,7 @@ class _ExitTransition extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return null; // unreachable
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,9 +475,8 @@ class _ExitTransition extends StatelessWidget {
|
|||||||
class _FlippedCurveTween extends CurveTween {
|
class _FlippedCurveTween extends CurveTween {
|
||||||
/// Creates a vertically flipped [CurveTween].
|
/// Creates a vertically flipped [CurveTween].
|
||||||
_FlippedCurveTween({
|
_FlippedCurveTween({
|
||||||
@required Curve curve,
|
required Curve curve,
|
||||||
}) : assert(curve != null),
|
}) : super(curve: curve);
|
||||||
super(curve: curve);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
double transform(double t) => 1.0 - super.transform(t);
|
double transform(double t) => 1.0 - super.transform(t);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
name: animations
|
name: animations
|
||||||
description: Fancy pre-built animations that can easily be integrated into any Flutter application.
|
description: Fancy pre-built animations that can easily be integrated into any Flutter application.
|
||||||
version: 1.1.2
|
version: 2.0.0-nullsafety.0
|
||||||
homepage: https://github.com/flutter/packages/tree/master/packages/animations
|
homepage: https://github.com/flutter/packages/tree/master/packages/animations
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.2.2 <3.0.0"
|
sdk: '>=2.12.0-0 <3.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
@ -13,4 +13,4 @@ dependencies:
|
|||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
vector_math: ^2.0.8
|
vector_math: ">=2.1.0-nullsafety.5 <3.0.0"
|
||||||
|
@ -2,10 +2,6 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
// TODO(shihaohong): Remove DualTransitionBuilder once flutter/flutter's `stable`
|
|
||||||
// branch contains DualTransitionBuilder.
|
|
||||||
import 'package:animations/src/dual_transition_builder.dart'
|
|
||||||
as dual_transition_builder;
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
@ -18,12 +14,12 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await tester.pumpWidget(Center(
|
await tester.pumpWidget(Center(
|
||||||
child: dual_transition_builder.DualTransitionBuilder(
|
child: DualTransitionBuilder(
|
||||||
animation: controller,
|
animation: controller,
|
||||||
forwardBuilder: (
|
forwardBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return ScaleTransition(
|
return ScaleTransition(
|
||||||
scale: animation,
|
scale: animation,
|
||||||
@ -33,7 +29,7 @@ void main() {
|
|||||||
reverseBuilder: (
|
reverseBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
|
opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
|
||||||
@ -88,12 +84,12 @@ void main() {
|
|||||||
await tester.pumpWidget(Directionality(
|
await tester.pumpWidget(Directionality(
|
||||||
textDirection: TextDirection.ltr,
|
textDirection: TextDirection.ltr,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: dual_transition_builder.DualTransitionBuilder(
|
child: DualTransitionBuilder(
|
||||||
animation: controller,
|
animation: controller,
|
||||||
forwardBuilder: (
|
forwardBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return ScaleTransition(
|
return ScaleTransition(
|
||||||
scale: animation,
|
scale: animation,
|
||||||
@ -103,7 +99,7 @@ void main() {
|
|||||||
reverseBuilder: (
|
reverseBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
|
opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
|
||||||
@ -150,12 +146,12 @@ void main() {
|
|||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
);
|
);
|
||||||
await tester.pumpWidget(Center(
|
await tester.pumpWidget(Center(
|
||||||
child: dual_transition_builder.DualTransitionBuilder(
|
child: DualTransitionBuilder(
|
||||||
animation: controller,
|
animation: controller,
|
||||||
forwardBuilder: (
|
forwardBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return ScaleTransition(
|
return ScaleTransition(
|
||||||
scale: animation,
|
scale: animation,
|
||||||
@ -165,7 +161,7 @@ void main() {
|
|||||||
reverseBuilder: (
|
reverseBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
|
opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
|
||||||
@ -216,12 +212,12 @@ void main() {
|
|||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
);
|
);
|
||||||
await tester.pumpWidget(Center(
|
await tester.pumpWidget(Center(
|
||||||
child: dual_transition_builder.DualTransitionBuilder(
|
child: DualTransitionBuilder(
|
||||||
animation: controller,
|
animation: controller,
|
||||||
forwardBuilder: (
|
forwardBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return ScaleTransition(
|
return ScaleTransition(
|
||||||
scale: animation,
|
scale: animation,
|
||||||
@ -231,7 +227,7 @@ void main() {
|
|||||||
reverseBuilder: (
|
reverseBuilder: (
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Widget child,
|
Widget? child,
|
||||||
) {
|
) {
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
|
opacity: Tween<double>(begin: 1.0, end: 0.0).animate(animation),
|
||||||
@ -286,7 +282,7 @@ double _getOpacity(WidgetTester tester) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _StatefulTestWidget extends StatefulWidget {
|
class _StatefulTestWidget extends StatefulWidget {
|
||||||
const _StatefulTestWidget({Key key, this.name}) : super(key: key);
|
const _StatefulTestWidget({Key? key, required this.name}) : super(key: key);
|
||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
|
@ -455,7 +455,7 @@ double _getOpacity(GlobalKey key, WidgetTester tester) {
|
|||||||
matching: find.byType(FadeTransition),
|
matching: find.byType(FadeTransition),
|
||||||
);
|
);
|
||||||
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
||||||
final FadeTransition transition = widget;
|
final FadeTransition transition = widget as FadeTransition;
|
||||||
return a * transition.opacity.value;
|
return a * transition.opacity.value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -466,18 +466,18 @@ double _getScale(GlobalKey key, WidgetTester tester) {
|
|||||||
matching: find.byType(ScaleTransition),
|
matching: find.byType(ScaleTransition),
|
||||||
);
|
);
|
||||||
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
||||||
final ScaleTransition transition = widget;
|
final ScaleTransition transition = widget as ScaleTransition;
|
||||||
return a * transition.scale.value;
|
return a * transition.scale.value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FlutterLogoModal extends StatefulWidget {
|
class _FlutterLogoModal extends StatefulWidget {
|
||||||
const _FlutterLogoModal({
|
const _FlutterLogoModal({
|
||||||
Key key,
|
Key? key,
|
||||||
this.name,
|
this.name,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String name;
|
final String? name;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_FlutterLogoModalState createState() => _FlutterLogoModalState();
|
_FlutterLogoModalState createState() => _FlutterLogoModalState();
|
||||||
|
@ -47,7 +47,7 @@ void main() {
|
|||||||
expect(_getOpacity(bottomRoute, tester), 1.0);
|
expect(_getOpacity(bottomRoute, tester), 1.0);
|
||||||
expect(find.text(topRoute), findsNothing);
|
expect(find.text(topRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ void main() {
|
|||||||
navigatorKey: navigator,
|
navigatorKey: navigator,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
navigator.currentState.pushNamed('/a');
|
navigator.currentState!.pushNamed('/a');
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(find.text(topRoute), findsOneWidget);
|
expect(find.text(topRoute), findsOneWidget);
|
||||||
@ -135,7 +135,7 @@ void main() {
|
|||||||
expect(_getOpacity(topRoute, tester), 1.0);
|
expect(_getOpacity(topRoute, tester), 1.0);
|
||||||
expect(find.text(bottomRoute), findsNothing);
|
expect(find.text(bottomRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Top route is full size and fully visible.
|
// Top route is full size and fully visible.
|
||||||
@ -223,7 +223,7 @@ void main() {
|
|||||||
expect(find.text(bottomRoute), findsOneWidget);
|
expect(find.text(bottomRoute), findsOneWidget);
|
||||||
expect(find.text(topRoute), findsNothing);
|
expect(find.text(topRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Jump to halfway point of transition.
|
// Jump to halfway point of transition.
|
||||||
@ -242,7 +242,7 @@ void main() {
|
|||||||
expect(topOpacity, lessThan(1.0));
|
expect(topOpacity, lessThan(1.0));
|
||||||
|
|
||||||
// Interrupt the transition with a pop.
|
// Interrupt the transition with a pop.
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
// Noting changed.
|
// Noting changed.
|
||||||
expect(find.text(bottomRoute), findsOneWidget);
|
expect(find.text(bottomRoute), findsOneWidget);
|
||||||
@ -288,7 +288,7 @@ void main() {
|
|||||||
navigatorKey: navigator,
|
navigatorKey: navigator,
|
||||||
contentBuilder: (RouteSettings settings) {
|
contentBuilder: (RouteSettings settings) {
|
||||||
return _StatefulTestWidget(
|
return _StatefulTestWidget(
|
||||||
key: ValueKey<String>(settings.name),
|
key: ValueKey<String?>(settings.name),
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -296,73 +296,73 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final _StatefulTestWidgetState bottomState =
|
final _StatefulTestWidgetState bottomState =
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute)));
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute)));
|
||||||
expect(bottomState.widget.name, bottomRoute);
|
expect(bottomState.widget.name, bottomRoute);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
final _StatefulTestWidgetState topState = tester.state(
|
final _StatefulTestWidgetState topState = tester.state(
|
||||||
find.byKey(const ValueKey<String>(topRoute)),
|
find.byKey(const ValueKey<String?>(topRoute)),
|
||||||
);
|
);
|
||||||
expect(topState.widget.name, topRoute);
|
expect(topState.widget.name, topRoute);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 150));
|
await tester.pump(const Duration(milliseconds: 150));
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(
|
tester.state(find.byKey(
|
||||||
const ValueKey<String>(bottomRoute),
|
const ValueKey<String?>(bottomRoute),
|
||||||
skipOffstage: false,
|
skipOffstage: false,
|
||||||
)),
|
)),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 150));
|
await tester.pump(const Duration(milliseconds: 150));
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(find.byKey(const ValueKey<String>(topRoute)), findsNothing);
|
expect(find.byKey(const ValueKey<String?>(topRoute)), findsNothing);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should keep state', (WidgetTester tester) async {
|
testWidgets('should keep state', (WidgetTester tester) async {
|
||||||
@ -433,22 +433,22 @@ void main() {
|
|||||||
|
|
||||||
double _getOpacity(String key, WidgetTester tester) {
|
double _getOpacity(String key, WidgetTester tester) {
|
||||||
final Finder finder = find.ancestor(
|
final Finder finder = find.ancestor(
|
||||||
of: find.byKey(ValueKey<String>(key)),
|
of: find.byKey(ValueKey<String?>(key)),
|
||||||
matching: find.byType(FadeTransition),
|
matching: find.byType(FadeTransition),
|
||||||
);
|
);
|
||||||
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
||||||
final FadeTransition transition = widget;
|
final FadeTransition transition = widget as FadeTransition;
|
||||||
return a * transition.opacity.value;
|
return a * transition.opacity.value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
double _getScale(String key, WidgetTester tester) {
|
double _getScale(String key, WidgetTester tester) {
|
||||||
final Finder finder = find.ancestor(
|
final Finder finder = find.ancestor(
|
||||||
of: find.byKey(ValueKey<String>(key)),
|
of: find.byKey(ValueKey<String?>(key)),
|
||||||
matching: find.byType(ScaleTransition),
|
matching: find.byType(ScaleTransition),
|
||||||
);
|
);
|
||||||
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
||||||
final ScaleTransition transition = widget;
|
final ScaleTransition transition = widget as ScaleTransition;
|
||||||
return a * transition.scale.value;
|
return a * transition.scale.value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -456,13 +456,13 @@ double _getScale(String key, WidgetTester tester) {
|
|||||||
class _TestWidget extends StatelessWidget {
|
class _TestWidget extends StatelessWidget {
|
||||||
const _TestWidget({this.navigatorKey, this.contentBuilder});
|
const _TestWidget({this.navigatorKey, this.contentBuilder});
|
||||||
|
|
||||||
final Key navigatorKey;
|
final Key? navigatorKey;
|
||||||
final _ContentBuilder contentBuilder;
|
final _ContentBuilder? contentBuilder;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: navigatorKey as GlobalKey<NavigatorState>?,
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
platform: TargetPlatform.android,
|
platform: TargetPlatform.android,
|
||||||
pageTransitionsTheme: const PageTransitionsTheme(
|
pageTransitionsTheme: const PageTransitionsTheme(
|
||||||
@ -476,11 +476,11 @@ class _TestWidget extends StatelessWidget {
|
|||||||
settings: settings,
|
settings: settings,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return contentBuilder != null
|
return contentBuilder != null
|
||||||
? contentBuilder(settings)
|
? contentBuilder!(settings)
|
||||||
: Container(
|
: Container(
|
||||||
child: Center(
|
child: Center(
|
||||||
key: ValueKey<String>(settings.name),
|
key: ValueKey<String?>(settings.name),
|
||||||
child: Text(settings.name),
|
child: Text(settings.name!),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -491,9 +491,9 @@ class _TestWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _StatefulTestWidget extends StatefulWidget {
|
class _StatefulTestWidget extends StatefulWidget {
|
||||||
const _StatefulTestWidget({Key key, this.name}) : super(key: key);
|
const _StatefulTestWidget({Key? key, this.name}) : super(key: key);
|
||||||
|
|
||||||
final String name;
|
final String? name;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_StatefulTestWidget> createState() => _StatefulTestWidgetState();
|
State<_StatefulTestWidget> createState() => _StatefulTestWidgetState();
|
||||||
@ -502,7 +502,7 @@ class _StatefulTestWidget extends StatefulWidget {
|
|||||||
class _StatefulTestWidgetState extends State<_StatefulTestWidget> {
|
class _StatefulTestWidgetState extends State<_StatefulTestWidget> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Text(widget.name);
|
return Text(widget.name!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,7 +464,7 @@ double _getOpacity(GlobalKey key, WidgetTester tester) {
|
|||||||
matching: find.byType(FadeTransition),
|
matching: find.byType(FadeTransition),
|
||||||
);
|
);
|
||||||
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
||||||
final FadeTransition transition = widget;
|
final FadeTransition transition = widget as FadeTransition;
|
||||||
return a * transition.opacity.value;
|
return a * transition.opacity.value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -475,18 +475,18 @@ double _getScale(GlobalKey key, WidgetTester tester) {
|
|||||||
matching: find.byType(ScaleTransition),
|
matching: find.byType(ScaleTransition),
|
||||||
);
|
);
|
||||||
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
||||||
final ScaleTransition transition = widget;
|
final ScaleTransition transition = widget as ScaleTransition;
|
||||||
return a * transition.scale.value;
|
return a * transition.scale.value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FlutterLogoModal extends StatefulWidget {
|
class _FlutterLogoModal extends StatefulWidget {
|
||||||
const _FlutterLogoModal({
|
const _FlutterLogoModal({
|
||||||
Key key,
|
Key? key,
|
||||||
this.name,
|
this.name,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String name;
|
final String? name;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_FlutterLogoModalState createState() => _FlutterLogoModalState();
|
_FlutterLogoModalState createState() => _FlutterLogoModalState();
|
||||||
@ -516,8 +516,7 @@ class _TestModalConfiguration extends ModalConfiguration {
|
|||||||
String barrierLabel = 'customLabel',
|
String barrierLabel = 'customLabel',
|
||||||
Duration transitionDuration = const Duration(milliseconds: 300),
|
Duration transitionDuration = const Duration(milliseconds: 300),
|
||||||
Duration reverseTransitionDuration = const Duration(milliseconds: 200),
|
Duration reverseTransitionDuration = const Duration(milliseconds: 200),
|
||||||
}) : assert(barrierDismissible != null),
|
}) : super(
|
||||||
super(
|
|
||||||
barrierColor: barrierColor,
|
barrierColor: barrierColor,
|
||||||
barrierDismissible: barrierDismissible,
|
barrierDismissible: barrierDismissible,
|
||||||
barrierLabel: barrierLabel,
|
barrierLabel: barrierLabel,
|
||||||
|
@ -44,7 +44,7 @@ void main() {
|
|||||||
matching: find.byType(Material),
|
matching: find.byType(Material),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
final Material srcMaterial = srcMaterialElement.widget;
|
final Material srcMaterial = srcMaterialElement.widget as Material;
|
||||||
expect(srcMaterial.color, Colors.green);
|
expect(srcMaterial.color, Colors.green);
|
||||||
expect(srcMaterial.elevation, 4.0);
|
expect(srcMaterial.elevation, 4.0);
|
||||||
expect(srcMaterial.shape, shape);
|
expect(srcMaterial.shape, shape);
|
||||||
@ -69,7 +69,7 @@ void main() {
|
|||||||
matching: find.byType(Material),
|
matching: find.byType(Material),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
final Material closedMaterial = destMaterialElement.widget;
|
final Material closedMaterial = destMaterialElement.widget as Material;
|
||||||
expect(closedMaterial.color, Colors.green);
|
expect(closedMaterial.color, Colors.green);
|
||||||
expect(closedMaterial.elevation, 4.0);
|
expect(closedMaterial.elevation, 4.0);
|
||||||
expect(closedMaterial.shape, shape);
|
expect(closedMaterial.shape, shape);
|
||||||
@ -90,7 +90,7 @@ void main() {
|
|||||||
// Jump to the start of the fade in.
|
// Jump to the start of the fade in.
|
||||||
await tester.pump(const Duration(milliseconds: 60)); // 300ms * 1/5 = 60ms
|
await tester.pump(const Duration(milliseconds: 60)); // 300ms * 1/5 = 60ms
|
||||||
final _TrackedData dataPreFade = _TrackedData(
|
final _TrackedData dataPreFade = _TrackedData(
|
||||||
destMaterialElement.widget,
|
destMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == destMaterialElement),
|
find.byElementPredicate((Element e) => e == destMaterialElement),
|
||||||
),
|
),
|
||||||
@ -107,7 +107,7 @@ void main() {
|
|||||||
await tester
|
await tester
|
||||||
.pump(const Duration(milliseconds: 30)); // 300ms * 3/10 = 90ms
|
.pump(const Duration(milliseconds: 30)); // 300ms * 3/10 = 90ms
|
||||||
final _TrackedData dataMidFadeIn = _TrackedData(
|
final _TrackedData dataMidFadeIn = _TrackedData(
|
||||||
destMaterialElement.widget,
|
destMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == destMaterialElement),
|
find.byElementPredicate((Element e) => e == destMaterialElement),
|
||||||
),
|
),
|
||||||
@ -128,7 +128,7 @@ void main() {
|
|||||||
); // 300ms * 2/5 = 120ms
|
); // 300ms * 2/5 = 120ms
|
||||||
|
|
||||||
final _TrackedData dataPostFadeIn = _TrackedData(
|
final _TrackedData dataPostFadeIn = _TrackedData(
|
||||||
destMaterialElement.widget,
|
destMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == destMaterialElement),
|
find.byElementPredicate((Element e) => e == destMaterialElement),
|
||||||
),
|
),
|
||||||
@ -144,7 +144,7 @@ void main() {
|
|||||||
// Jump almost to the end of the transition.
|
// Jump almost to the end of the transition.
|
||||||
await tester.pump(const Duration(milliseconds: 180));
|
await tester.pump(const Duration(milliseconds: 180));
|
||||||
final _TrackedData dataTransitionDone = _TrackedData(
|
final _TrackedData dataTransitionDone = _TrackedData(
|
||||||
destMaterialElement.widget,
|
destMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == destMaterialElement),
|
find.byElementPredicate((Element e) => e == destMaterialElement),
|
||||||
),
|
),
|
||||||
@ -170,7 +170,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
final _TrackedData dataOpen = _TrackedData(
|
final _TrackedData dataOpen = _TrackedData(
|
||||||
finalMaterialElement.widget,
|
finalMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == finalMaterialElement),
|
find.byElementPredicate((Element e) => e == finalMaterialElement),
|
||||||
),
|
),
|
||||||
@ -221,7 +221,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
final _TrackedData dataOpen = _TrackedData(
|
final _TrackedData dataOpen = _TrackedData(
|
||||||
initialMaterialElement.widget,
|
initialMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == initialMaterialElement),
|
find.byElementPredicate((Element e) => e == initialMaterialElement),
|
||||||
),
|
),
|
||||||
@ -245,7 +245,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
final _TrackedData dataTransitionStart = _TrackedData(
|
final _TrackedData dataTransitionStart = _TrackedData(
|
||||||
materialElement.widget,
|
materialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == materialElement),
|
find.byElementPredicate((Element e) => e == materialElement),
|
||||||
),
|
),
|
||||||
@ -261,7 +261,7 @@ void main() {
|
|||||||
// Jump to start of fade out: 1/5 of 300.
|
// Jump to start of fade out: 1/5 of 300.
|
||||||
await tester.pump(const Duration(milliseconds: 60)); // 300 * 1/5 = 60
|
await tester.pump(const Duration(milliseconds: 60)); // 300 * 1/5 = 60
|
||||||
final _TrackedData dataPreFadeOut = _TrackedData(
|
final _TrackedData dataPreFadeOut = _TrackedData(
|
||||||
materialElement.widget,
|
materialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == materialElement),
|
find.byElementPredicate((Element e) => e == materialElement),
|
||||||
),
|
),
|
||||||
@ -277,7 +277,7 @@ void main() {
|
|||||||
// Jump to the middle of the fade out.
|
// Jump to the middle of the fade out.
|
||||||
await tester.pump(const Duration(milliseconds: 30)); // 300 * 3/10 = 90
|
await tester.pump(const Duration(milliseconds: 30)); // 300 * 3/10 = 90
|
||||||
final _TrackedData dataMidpoint = _TrackedData(
|
final _TrackedData dataMidpoint = _TrackedData(
|
||||||
materialElement.widget,
|
materialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == materialElement),
|
find.byElementPredicate((Element e) => e == materialElement),
|
||||||
),
|
),
|
||||||
@ -295,7 +295,7 @@ void main() {
|
|||||||
// Jump to the end of the fade out.
|
// Jump to the end of the fade out.
|
||||||
await tester.pump(const Duration(milliseconds: 30)); // 300 * 2/5 = 120
|
await tester.pump(const Duration(milliseconds: 30)); // 300 * 2/5 = 120
|
||||||
final _TrackedData dataPostFadeOut = _TrackedData(
|
final _TrackedData dataPostFadeOut = _TrackedData(
|
||||||
materialElement.widget,
|
materialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == materialElement),
|
find.byElementPredicate((Element e) => e == materialElement),
|
||||||
),
|
),
|
||||||
@ -311,7 +311,7 @@ void main() {
|
|||||||
// Jump almost to the end of the transition.
|
// Jump almost to the end of the transition.
|
||||||
await tester.pump(const Duration(milliseconds: 180));
|
await tester.pump(const Duration(milliseconds: 180));
|
||||||
final _TrackedData dataTransitionDone = _TrackedData(
|
final _TrackedData dataTransitionDone = _TrackedData(
|
||||||
materialElement.widget,
|
materialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == materialElement),
|
find.byElementPredicate((Element e) => e == materialElement),
|
||||||
),
|
),
|
||||||
@ -337,7 +337,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
final _TrackedData dataClosed = _TrackedData(
|
final _TrackedData dataClosed = _TrackedData(
|
||||||
finalMaterialElement.widget,
|
finalMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == finalMaterialElement),
|
find.byElementPredicate((Element e) => e == finalMaterialElement),
|
||||||
),
|
),
|
||||||
@ -388,7 +388,7 @@ void main() {
|
|||||||
matching: find.byType(Material),
|
matching: find.byType(Material),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
final Material srcMaterial = srcMaterialElement.widget;
|
final Material srcMaterial = srcMaterialElement.widget as Material;
|
||||||
expect(srcMaterial.color, Colors.green);
|
expect(srcMaterial.color, Colors.green);
|
||||||
expect(srcMaterial.elevation, 4.0);
|
expect(srcMaterial.elevation, 4.0);
|
||||||
expect(srcMaterial.shape, shape);
|
expect(srcMaterial.shape, shape);
|
||||||
@ -413,7 +413,7 @@ void main() {
|
|||||||
matching: find.byType(Material),
|
matching: find.byType(Material),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
final Material closedMaterial = destMaterialElement.widget;
|
final Material closedMaterial = destMaterialElement.widget as Material;
|
||||||
expect(closedMaterial.color, Colors.green);
|
expect(closedMaterial.color, Colors.green);
|
||||||
expect(closedMaterial.elevation, 4.0);
|
expect(closedMaterial.elevation, 4.0);
|
||||||
expect(closedMaterial.shape, shape);
|
expect(closedMaterial.shape, shape);
|
||||||
@ -434,7 +434,7 @@ void main() {
|
|||||||
// The fade-out takes 1/5 of 300ms. Let's jump to the midpoint of that.
|
// The fade-out takes 1/5 of 300ms. Let's jump to the midpoint of that.
|
||||||
await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/10 = 30ms
|
await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/10 = 30ms
|
||||||
final _TrackedData dataMidFadeOut = _TrackedData(
|
final _TrackedData dataMidFadeOut = _TrackedData(
|
||||||
destMaterialElement.widget,
|
destMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == destMaterialElement),
|
find.byElementPredicate((Element e) => e == destMaterialElement),
|
||||||
),
|
),
|
||||||
@ -452,7 +452,7 @@ void main() {
|
|||||||
// Let's jump to the crossover point at 1/5 of 300ms.
|
// Let's jump to the crossover point at 1/5 of 300ms.
|
||||||
await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/5 = 60ms
|
await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/5 = 60ms
|
||||||
final _TrackedData dataMidpoint = _TrackedData(
|
final _TrackedData dataMidpoint = _TrackedData(
|
||||||
destMaterialElement.widget,
|
destMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == destMaterialElement),
|
find.byElementPredicate((Element e) => e == destMaterialElement),
|
||||||
),
|
),
|
||||||
@ -469,7 +469,7 @@ void main() {
|
|||||||
// Let's jump to the middle of the fade-in at 3/5 of 300ms
|
// Let's jump to the middle of the fade-in at 3/5 of 300ms
|
||||||
await tester.pump(const Duration(milliseconds: 120)); // 300ms * 3/5 = 180ms
|
await tester.pump(const Duration(milliseconds: 120)); // 300ms * 3/5 = 180ms
|
||||||
final _TrackedData dataMidFadeIn = _TrackedData(
|
final _TrackedData dataMidFadeIn = _TrackedData(
|
||||||
destMaterialElement.widget,
|
destMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == destMaterialElement),
|
find.byElementPredicate((Element e) => e == destMaterialElement),
|
||||||
),
|
),
|
||||||
@ -487,7 +487,7 @@ void main() {
|
|||||||
// Let's jump almost to the end of the transition.
|
// Let's jump almost to the end of the transition.
|
||||||
await tester.pump(const Duration(milliseconds: 120));
|
await tester.pump(const Duration(milliseconds: 120));
|
||||||
final _TrackedData dataTransitionDone = _TrackedData(
|
final _TrackedData dataTransitionDone = _TrackedData(
|
||||||
destMaterialElement.widget,
|
destMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == destMaterialElement),
|
find.byElementPredicate((Element e) => e == destMaterialElement),
|
||||||
),
|
),
|
||||||
@ -518,7 +518,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
final _TrackedData dataOpen = _TrackedData(
|
final _TrackedData dataOpen = _TrackedData(
|
||||||
finalMaterialElement.widget,
|
finalMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == finalMaterialElement),
|
find.byElementPredicate((Element e) => e == finalMaterialElement),
|
||||||
),
|
),
|
||||||
@ -567,7 +567,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
final _TrackedData dataOpen = _TrackedData(
|
final _TrackedData dataOpen = _TrackedData(
|
||||||
initialMaterialElement.widget,
|
initialMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == initialMaterialElement),
|
find.byElementPredicate((Element e) => e == initialMaterialElement),
|
||||||
),
|
),
|
||||||
@ -591,7 +591,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
final _TrackedData dataTransitionStart = _TrackedData(
|
final _TrackedData dataTransitionStart = _TrackedData(
|
||||||
materialElement.widget,
|
materialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == materialElement),
|
find.byElementPredicate((Element e) => e == materialElement),
|
||||||
),
|
),
|
||||||
@ -606,7 +606,7 @@ void main() {
|
|||||||
// Jump to mid-point of fade-out: 1/10 of 300ms.
|
// Jump to mid-point of fade-out: 1/10 of 300ms.
|
||||||
await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/10 = 30ms
|
await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/10 = 30ms
|
||||||
final _TrackedData dataMidFadeOut = _TrackedData(
|
final _TrackedData dataMidFadeOut = _TrackedData(
|
||||||
materialElement.widget,
|
materialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == materialElement),
|
find.byElementPredicate((Element e) => e == materialElement),
|
||||||
),
|
),
|
||||||
@ -627,7 +627,7 @@ void main() {
|
|||||||
// Let's jump to the crossover point at 1/5 of 300ms.
|
// Let's jump to the crossover point at 1/5 of 300ms.
|
||||||
await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/5 = 60ms
|
await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/5 = 60ms
|
||||||
final _TrackedData dataMidpoint = _TrackedData(
|
final _TrackedData dataMidpoint = _TrackedData(
|
||||||
materialElement.widget,
|
materialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == materialElement),
|
find.byElementPredicate((Element e) => e == materialElement),
|
||||||
),
|
),
|
||||||
@ -644,7 +644,7 @@ void main() {
|
|||||||
// Let's jump to the middle of the fade-in at 3/5 of 300ms
|
// Let's jump to the middle of the fade-in at 3/5 of 300ms
|
||||||
await tester.pump(const Duration(milliseconds: 120)); // 300ms * 3/5 = 180ms
|
await tester.pump(const Duration(milliseconds: 120)); // 300ms * 3/5 = 180ms
|
||||||
final _TrackedData dataMidFadeIn = _TrackedData(
|
final _TrackedData dataMidFadeIn = _TrackedData(
|
||||||
materialElement.widget,
|
materialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == materialElement),
|
find.byElementPredicate((Element e) => e == materialElement),
|
||||||
),
|
),
|
||||||
@ -662,7 +662,7 @@ void main() {
|
|||||||
// Let's jump almost to the end of the transition.
|
// Let's jump almost to the end of the transition.
|
||||||
await tester.pump(const Duration(milliseconds: 120));
|
await tester.pump(const Duration(milliseconds: 120));
|
||||||
final _TrackedData dataTransitionDone = _TrackedData(
|
final _TrackedData dataTransitionDone = _TrackedData(
|
||||||
materialElement.widget,
|
materialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == materialElement),
|
find.byElementPredicate((Element e) => e == materialElement),
|
||||||
),
|
),
|
||||||
@ -692,7 +692,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
final _TrackedData dataClosed = _TrackedData(
|
final _TrackedData dataClosed = _TrackedData(
|
||||||
finalMaterialElement.widget,
|
finalMaterialElement.widget as Material,
|
||||||
tester.getRect(
|
tester.getRect(
|
||||||
find.byElementPredicate((Element e) => e == finalMaterialElement),
|
find.byElementPredicate((Element e) => e == finalMaterialElement),
|
||||||
),
|
),
|
||||||
@ -731,7 +731,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Action callbacks work', (WidgetTester tester) async {
|
testWidgets('Action callbacks work', (WidgetTester tester) async {
|
||||||
VoidCallback open, close;
|
late VoidCallback open, close;
|
||||||
await tester.pumpWidget(_boilerplate(
|
await tester.pumpWidget(_boilerplate(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: OpenContainer(
|
child: OpenContainer(
|
||||||
@ -805,7 +805,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('closed widget keeps state', (WidgetTester tester) async {
|
testWidgets('closed widget keeps state', (WidgetTester tester) async {
|
||||||
VoidCallback open;
|
late VoidCallback open;
|
||||||
await tester.pumpWidget(_boilerplate(
|
await tester.pumpWidget(_boilerplate(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: OpenContainer(
|
child: OpenContainer(
|
||||||
@ -1530,9 +1530,9 @@ void main() {
|
|||||||
testWidgets(
|
testWidgets(
|
||||||
'onClosed callback receives popped value when container has closed',
|
'onClosed callback receives popped value when container has closed',
|
||||||
(WidgetTester tester) async {
|
(WidgetTester tester) async {
|
||||||
bool value = false;
|
bool? value = false;
|
||||||
final Widget openContainer = OpenContainer<bool>(
|
final Widget openContainer = OpenContainer<bool>(
|
||||||
onClosed: (bool poppedValue) {
|
onClosed: (bool? poppedValue) {
|
||||||
value = poppedValue;
|
value = poppedValue;
|
||||||
},
|
},
|
||||||
closedBuilder: (BuildContext context, VoidCallback action) {
|
closedBuilder: (BuildContext context, VoidCallback action) {
|
||||||
@ -1573,9 +1573,9 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Widget _createRootNavigatorTest({
|
Widget _createRootNavigatorTest({
|
||||||
@required Key appKey,
|
required Key appKey,
|
||||||
@required Key nestedNavigatorKey,
|
required Key nestedNavigatorKey,
|
||||||
@required bool useRootNavigator,
|
required bool useRootNavigator,
|
||||||
}) {
|
}) {
|
||||||
return Center(
|
return Center(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
@ -1729,7 +1729,7 @@ void main() {
|
|||||||
// equal to the RouteSettings passed to the OpenContainer
|
// equal to the RouteSettings passed to the OpenContainer
|
||||||
final ModalRoute<dynamic> modalRoute = ModalRoute.of(
|
final ModalRoute<dynamic> modalRoute = ModalRoute.of(
|
||||||
tester.element(find.text('Open')),
|
tester.element(find.text('Open')),
|
||||||
);
|
)!;
|
||||||
expect(modalRoute.settings, routeSettings);
|
expect(modalRoute.settings, routeSettings);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -1781,9 +1781,9 @@ Color _getScrimColor(WidgetTester tester) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _expectMaterialPropertiesHaveAdvanced({
|
void _expectMaterialPropertiesHaveAdvanced({
|
||||||
@required _TrackedData biggerMaterial,
|
required _TrackedData biggerMaterial,
|
||||||
@required _TrackedData smallerMaterial,
|
required _TrackedData smallerMaterial,
|
||||||
@required WidgetTester tester,
|
required WidgetTester tester,
|
||||||
}) {
|
}) {
|
||||||
expect(
|
expect(
|
||||||
biggerMaterial.material.elevation,
|
biggerMaterial.material.elevation,
|
||||||
@ -1814,15 +1814,16 @@ class _TrackedData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double _getRadius(Material material) {
|
double _getRadius(Material material) {
|
||||||
final RoundedRectangleBorder shape = material.shape;
|
final RoundedRectangleBorder? shape =
|
||||||
|
material.shape as RoundedRectangleBorder?;
|
||||||
if (shape == null) {
|
if (shape == null) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
final BorderRadius radius = shape.borderRadius;
|
final BorderRadius radius = shape.borderRadius as BorderRadius;
|
||||||
return radius.topRight.x;
|
return radius.topRight.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _boilerplate({@required Widget child}) {
|
Widget _boilerplate({required Widget child}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
home: Scaffold(
|
home: Scaffold(
|
||||||
body: child,
|
body: child,
|
||||||
@ -1831,7 +1832,7 @@ Widget _boilerplate({@required Widget child}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SizableContainer extends StatefulWidget {
|
class _SizableContainer extends StatefulWidget {
|
||||||
const _SizableContainer({this.initialSize, this.child});
|
const _SizableContainer({required this.initialSize, required this.child});
|
||||||
|
|
||||||
final double initialSize;
|
final double initialSize;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
@ -1842,7 +1843,7 @@ class _SizableContainer extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SizableContainerState extends State<_SizableContainer> {
|
class _SizableContainerState extends State<_SizableContainer> {
|
||||||
_SizableContainerState({double size}) : _size = size;
|
_SizableContainerState({required double size}) : _size = size;
|
||||||
|
|
||||||
double get size => _size;
|
double get size => _size;
|
||||||
double _size;
|
double _size;
|
||||||
|
@ -585,7 +585,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class StatefulTestWidget extends StatefulWidget {
|
class StatefulTestWidget extends StatefulWidget {
|
||||||
const StatefulTestWidget({Key key}) : super(key: key);
|
const StatefulTestWidget({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
StatefulTestWidgetState createState() => StatefulTestWidgetState();
|
StatefulTestWidgetState createState() => StatefulTestWidgetState();
|
||||||
|
@ -63,7 +63,7 @@ void main() {
|
|||||||
expect(_getOpacity(bottomRoute, tester), 1.0);
|
expect(_getOpacity(bottomRoute, tester), 1.0);
|
||||||
expect(find.text(topRoute), findsNothing);
|
expect(find.text(topRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ void main() {
|
|||||||
// Top route is still invisible, but moving towards the left.
|
// Top route is still invisible, but moving towards the left.
|
||||||
expect(find.text(topRoute), findsOneWidget);
|
expect(find.text(topRoute), findsOneWidget);
|
||||||
expect(_getOpacity(topRoute, tester), 0.0);
|
expect(_getOpacity(topRoute, tester), 0.0);
|
||||||
double topOffset = _getTranslationOffset(
|
double? topOffset = _getTranslationOffset(
|
||||||
topRoute,
|
topRoute,
|
||||||
tester,
|
tester,
|
||||||
SharedAxisTransitionType.horizontal,
|
SharedAxisTransitionType.horizontal,
|
||||||
@ -174,7 +174,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
navigator.currentState.pushNamed('/a');
|
navigator.currentState!.pushNamed('/a');
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(find.text(topRoute), findsOneWidget);
|
expect(find.text(topRoute), findsOneWidget);
|
||||||
@ -189,7 +189,7 @@ void main() {
|
|||||||
expect(_getOpacity(topRoute, tester), 1.0);
|
expect(_getOpacity(topRoute, tester), 1.0);
|
||||||
expect(find.text(bottomRoute), findsNothing);
|
expect(find.text(bottomRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Top route is is not offset and fully visible.
|
// Top route is is not offset and fully visible.
|
||||||
@ -228,7 +228,7 @@ void main() {
|
|||||||
expect(find.text(bottomRoute), findsOneWidget);
|
expect(find.text(bottomRoute), findsOneWidget);
|
||||||
expect(_getOpacity(bottomRoute, tester),
|
expect(_getOpacity(bottomRoute, tester),
|
||||||
moreOrLessEquals(0, epsilon: 0.005));
|
moreOrLessEquals(0, epsilon: 0.005));
|
||||||
double bottomOffset = _getTranslationOffset(
|
double? bottomOffset = _getTranslationOffset(
|
||||||
bottomRoute,
|
bottomRoute,
|
||||||
tester,
|
tester,
|
||||||
SharedAxisTransitionType.horizontal,
|
SharedAxisTransitionType.horizontal,
|
||||||
@ -300,7 +300,7 @@ void main() {
|
|||||||
expect(find.text(bottomRoute), findsOneWidget);
|
expect(find.text(bottomRoute), findsOneWidget);
|
||||||
expect(find.text(topRoute), findsNothing);
|
expect(find.text(topRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Jump to halfway point of transition.
|
// Jump to halfway point of transition.
|
||||||
@ -308,7 +308,7 @@ void main() {
|
|||||||
// Bottom route is fully faded out.
|
// Bottom route is fully faded out.
|
||||||
expect(find.text(bottomRoute), findsOneWidget);
|
expect(find.text(bottomRoute), findsOneWidget);
|
||||||
expect(_getOpacity(bottomRoute, tester), 0.0);
|
expect(_getOpacity(bottomRoute, tester), 0.0);
|
||||||
final double halfwayBottomOffset = _getTranslationOffset(
|
final double? halfwayBottomOffset = _getTranslationOffset(
|
||||||
bottomRoute,
|
bottomRoute,
|
||||||
tester,
|
tester,
|
||||||
SharedAxisTransitionType.horizontal,
|
SharedAxisTransitionType.horizontal,
|
||||||
@ -318,7 +318,7 @@ void main() {
|
|||||||
|
|
||||||
// Top route is fading/coming in.
|
// Top route is fading/coming in.
|
||||||
expect(find.text(topRoute), findsOneWidget);
|
expect(find.text(topRoute), findsOneWidget);
|
||||||
final double halfwayTopOffset = _getTranslationOffset(
|
final double? halfwayTopOffset = _getTranslationOffset(
|
||||||
topRoute,
|
topRoute,
|
||||||
tester,
|
tester,
|
||||||
SharedAxisTransitionType.horizontal,
|
SharedAxisTransitionType.horizontal,
|
||||||
@ -330,7 +330,7 @@ void main() {
|
|||||||
expect(halfwayTopOpacity, lessThan(1.0));
|
expect(halfwayTopOpacity, lessThan(1.0));
|
||||||
|
|
||||||
// Interrupt the transition with a pop.
|
// Interrupt the transition with a pop.
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Nothing should change.
|
// Nothing should change.
|
||||||
@ -426,8 +426,8 @@ void main() {
|
|||||||
navigatorKey: navigator,
|
navigatorKey: navigator,
|
||||||
contentBuilder: (RouteSettings settings) {
|
contentBuilder: (RouteSettings settings) {
|
||||||
return _StatefulTestWidget(
|
return _StatefulTestWidget(
|
||||||
key: ValueKey<String>(settings.name),
|
key: ValueKey<String?>(settings.name),
|
||||||
name: settings.name,
|
name: settings.name!,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
transitionType: SharedAxisTransitionType.horizontal,
|
transitionType: SharedAxisTransitionType.horizontal,
|
||||||
@ -435,74 +435,74 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final _StatefulTestWidgetState bottomState = tester.state(
|
final _StatefulTestWidgetState bottomState = tester.state(
|
||||||
find.byKey(const ValueKey<String>(bottomRoute)),
|
find.byKey(const ValueKey<String?>(bottomRoute)),
|
||||||
);
|
);
|
||||||
expect(bottomState.widget.name, bottomRoute);
|
expect(bottomState.widget.name, bottomRoute);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
final _StatefulTestWidgetState topState = tester.state(
|
final _StatefulTestWidgetState topState = tester.state(
|
||||||
find.byKey(const ValueKey<String>(topRoute)),
|
find.byKey(const ValueKey<String?>(topRoute)),
|
||||||
);
|
);
|
||||||
expect(topState.widget.name, topRoute);
|
expect(topState.widget.name, topRoute);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 150));
|
await tester.pump(const Duration(milliseconds: 150));
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(
|
tester.state(find.byKey(
|
||||||
const ValueKey<String>(bottomRoute),
|
const ValueKey<String?>(bottomRoute),
|
||||||
skipOffstage: false,
|
skipOffstage: false,
|
||||||
)),
|
)),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 150));
|
await tester.pump(const Duration(milliseconds: 150));
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(find.byKey(const ValueKey<String>(topRoute)), findsNothing);
|
expect(find.byKey(const ValueKey<String?>(topRoute)), findsNothing);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -525,21 +525,21 @@ void main() {
|
|||||||
Finder fillContainerFinder = find
|
Finder fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/')),
|
of: find.byKey(const ValueKey<String?>('/')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
expect(tester.widget<Container>(fillContainerFinder).color,
|
expect(tester.widget<Container>(fillContainerFinder).color,
|
||||||
defaultFillColor);
|
defaultFillColor);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
fillContainerFinder = find
|
fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/a')),
|
of: find.byKey(const ValueKey<String?>('/a')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
@ -564,20 +564,20 @@ void main() {
|
|||||||
Finder fillContainerFinder = find
|
Finder fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/')),
|
of: find.byKey(const ValueKey<String?>('/')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);
|
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
fillContainerFinder = find
|
fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/a')),
|
of: find.byKey(const ValueKey<String?>('/a')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
@ -704,7 +704,7 @@ void main() {
|
|||||||
expect(_getOpacity(bottomRoute, tester), 1.0);
|
expect(_getOpacity(bottomRoute, tester), 1.0);
|
||||||
expect(find.text(topRoute), findsNothing);
|
expect(find.text(topRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
@ -744,7 +744,7 @@ void main() {
|
|||||||
// Top route is still invisible, but moving up.
|
// Top route is still invisible, but moving up.
|
||||||
expect(find.text(topRoute), findsOneWidget);
|
expect(find.text(topRoute), findsOneWidget);
|
||||||
expect(_getOpacity(topRoute, tester), 0.0);
|
expect(_getOpacity(topRoute, tester), 0.0);
|
||||||
double topOffset = _getTranslationOffset(
|
double? topOffset = _getTranslationOffset(
|
||||||
topRoute,
|
topRoute,
|
||||||
tester,
|
tester,
|
||||||
SharedAxisTransitionType.vertical,
|
SharedAxisTransitionType.vertical,
|
||||||
@ -815,7 +815,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
navigator.currentState.pushNamed('/a');
|
navigator.currentState!.pushNamed('/a');
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(find.text(topRoute), findsOneWidget);
|
expect(find.text(topRoute), findsOneWidget);
|
||||||
@ -830,7 +830,7 @@ void main() {
|
|||||||
expect(_getOpacity(topRoute, tester), 1.0);
|
expect(_getOpacity(topRoute, tester), 1.0);
|
||||||
expect(find.text(bottomRoute), findsNothing);
|
expect(find.text(bottomRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Top route is is not offset and fully visible.
|
// Top route is is not offset and fully visible.
|
||||||
@ -871,7 +871,7 @@ void main() {
|
|||||||
_getOpacity(bottomRoute, tester),
|
_getOpacity(bottomRoute, tester),
|
||||||
moreOrLessEquals(0, epsilon: 0.005),
|
moreOrLessEquals(0, epsilon: 0.005),
|
||||||
);
|
);
|
||||||
double bottomOffset = _getTranslationOffset(
|
double? bottomOffset = _getTranslationOffset(
|
||||||
bottomRoute,
|
bottomRoute,
|
||||||
tester,
|
tester,
|
||||||
SharedAxisTransitionType.vertical,
|
SharedAxisTransitionType.vertical,
|
||||||
@ -943,7 +943,7 @@ void main() {
|
|||||||
expect(find.text(bottomRoute), findsOneWidget);
|
expect(find.text(bottomRoute), findsOneWidget);
|
||||||
expect(find.text(topRoute), findsNothing);
|
expect(find.text(topRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Jump to halfway point of transition.
|
// Jump to halfway point of transition.
|
||||||
@ -951,7 +951,7 @@ void main() {
|
|||||||
// Bottom route is fully faded out.
|
// Bottom route is fully faded out.
|
||||||
expect(find.text(bottomRoute), findsOneWidget);
|
expect(find.text(bottomRoute), findsOneWidget);
|
||||||
expect(_getOpacity(bottomRoute, tester), 0.0);
|
expect(_getOpacity(bottomRoute, tester), 0.0);
|
||||||
final double halfwayBottomOffset = _getTranslationOffset(
|
final double? halfwayBottomOffset = _getTranslationOffset(
|
||||||
bottomRoute,
|
bottomRoute,
|
||||||
tester,
|
tester,
|
||||||
SharedAxisTransitionType.vertical,
|
SharedAxisTransitionType.vertical,
|
||||||
@ -961,7 +961,7 @@ void main() {
|
|||||||
|
|
||||||
// Top route is fading/coming in.
|
// Top route is fading/coming in.
|
||||||
expect(find.text(topRoute), findsOneWidget);
|
expect(find.text(topRoute), findsOneWidget);
|
||||||
final double halfwayTopOffset = _getTranslationOffset(
|
final double? halfwayTopOffset = _getTranslationOffset(
|
||||||
topRoute,
|
topRoute,
|
||||||
tester,
|
tester,
|
||||||
SharedAxisTransitionType.vertical,
|
SharedAxisTransitionType.vertical,
|
||||||
@ -973,7 +973,7 @@ void main() {
|
|||||||
expect(halfwayTopOpacity, lessThan(1.0));
|
expect(halfwayTopOpacity, lessThan(1.0));
|
||||||
|
|
||||||
// Interrupt the transition with a pop.
|
// Interrupt the transition with a pop.
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Nothing should change.
|
// Nothing should change.
|
||||||
@ -1069,8 +1069,8 @@ void main() {
|
|||||||
navigatorKey: navigator,
|
navigatorKey: navigator,
|
||||||
contentBuilder: (RouteSettings settings) {
|
contentBuilder: (RouteSettings settings) {
|
||||||
return _StatefulTestWidget(
|
return _StatefulTestWidget(
|
||||||
key: ValueKey<String>(settings.name),
|
key: ValueKey<String?>(settings.name),
|
||||||
name: settings.name,
|
name: settings.name!,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
transitionType: SharedAxisTransitionType.vertical,
|
transitionType: SharedAxisTransitionType.vertical,
|
||||||
@ -1078,74 +1078,74 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final _StatefulTestWidgetState bottomState = tester.state(
|
final _StatefulTestWidgetState bottomState = tester.state(
|
||||||
find.byKey(const ValueKey<String>(bottomRoute)),
|
find.byKey(const ValueKey<String?>(bottomRoute)),
|
||||||
);
|
);
|
||||||
expect(bottomState.widget.name, bottomRoute);
|
expect(bottomState.widget.name, bottomRoute);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
final _StatefulTestWidgetState topState = tester.state(
|
final _StatefulTestWidgetState topState = tester.state(
|
||||||
find.byKey(const ValueKey<String>(topRoute)),
|
find.byKey(const ValueKey<String?>(topRoute)),
|
||||||
);
|
);
|
||||||
expect(topState.widget.name, topRoute);
|
expect(topState.widget.name, topRoute);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 150));
|
await tester.pump(const Duration(milliseconds: 150));
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(
|
tester.state(find.byKey(
|
||||||
const ValueKey<String>(bottomRoute),
|
const ValueKey<String?>(bottomRoute),
|
||||||
skipOffstage: false,
|
skipOffstage: false,
|
||||||
)),
|
)),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 150));
|
await tester.pump(const Duration(milliseconds: 150));
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(find.byKey(const ValueKey<String>(topRoute)), findsNothing);
|
expect(find.byKey(const ValueKey<String?>(topRoute)), findsNothing);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1168,21 +1168,21 @@ void main() {
|
|||||||
Finder fillContainerFinder = find
|
Finder fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/')),
|
of: find.byKey(const ValueKey<String?>('/')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
expect(tester.widget<Container>(fillContainerFinder).color,
|
expect(tester.widget<Container>(fillContainerFinder).color,
|
||||||
defaultFillColor);
|
defaultFillColor);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
fillContainerFinder = find
|
fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/a')),
|
of: find.byKey(const ValueKey<String?>('/a')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
@ -1207,20 +1207,20 @@ void main() {
|
|||||||
Finder fillContainerFinder = find
|
Finder fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/')),
|
of: find.byKey(const ValueKey<String?>('/')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);
|
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
fillContainerFinder = find
|
fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/a')),
|
of: find.byKey(const ValueKey<String?>('/a')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
@ -1340,7 +1340,7 @@ void main() {
|
|||||||
expect(_getOpacity(bottomRoute, tester), 1.0);
|
expect(_getOpacity(bottomRoute, tester), 1.0);
|
||||||
expect(find.text(topRoute), findsNothing);
|
expect(find.text(topRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
@ -1413,7 +1413,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(find.text(topRoute), findsOneWidget);
|
expect(find.text(topRoute), findsOneWidget);
|
||||||
@ -1421,7 +1421,7 @@ void main() {
|
|||||||
expect(_getOpacity(topRoute, tester), 1.0);
|
expect(_getOpacity(topRoute, tester), 1.0);
|
||||||
expect(find.text(bottomRoute), findsNothing);
|
expect(find.text(bottomRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Top route is full size and fully visible.
|
// Top route is full size and fully visible.
|
||||||
@ -1498,7 +1498,7 @@ void main() {
|
|||||||
expect(find.text(bottomRoute), findsOneWidget);
|
expect(find.text(bottomRoute), findsOneWidget);
|
||||||
expect(find.text(topRoute), findsNothing);
|
expect(find.text(topRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Jump to halfway point of transition.
|
// Jump to halfway point of transition.
|
||||||
@ -1520,7 +1520,7 @@ void main() {
|
|||||||
expect(halfwayTopOpacity, lessThan(1.0));
|
expect(halfwayTopOpacity, lessThan(1.0));
|
||||||
|
|
||||||
// Interrupt the transition with a pop.
|
// Interrupt the transition with a pop.
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Nothing should change.
|
// Nothing should change.
|
||||||
@ -1571,7 +1571,7 @@ void main() {
|
|||||||
expect(find.text(bottomRoute), findsOneWidget);
|
expect(find.text(bottomRoute), findsOneWidget);
|
||||||
expect(find.text(topRoute), findsNothing);
|
expect(find.text(topRoute), findsNothing);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
// Jump to halfway point of transition.
|
// Jump to halfway point of transition.
|
||||||
@ -1606,82 +1606,82 @@ void main() {
|
|||||||
transitionType: SharedAxisTransitionType.scaled,
|
transitionType: SharedAxisTransitionType.scaled,
|
||||||
contentBuilder: (RouteSettings settings) {
|
contentBuilder: (RouteSettings settings) {
|
||||||
return _StatefulTestWidget(
|
return _StatefulTestWidget(
|
||||||
key: ValueKey<String>(settings.name),
|
key: ValueKey<String?>(settings.name),
|
||||||
name: settings.name,
|
name: settings.name!,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final _StatefulTestWidgetState bottomState = tester.state(
|
final _StatefulTestWidgetState bottomState = tester.state(
|
||||||
find.byKey(const ValueKey<String>(bottomRoute)),
|
find.byKey(const ValueKey<String?>(bottomRoute)),
|
||||||
);
|
);
|
||||||
expect(bottomState.widget.name, bottomRoute);
|
expect(bottomState.widget.name, bottomRoute);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
final _StatefulTestWidgetState topState = tester.state(
|
final _StatefulTestWidgetState topState = tester.state(
|
||||||
find.byKey(const ValueKey<String>(topRoute)),
|
find.byKey(const ValueKey<String?>(topRoute)),
|
||||||
);
|
);
|
||||||
expect(topState.widget.name, topRoute);
|
expect(topState.widget.name, topRoute);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 150));
|
await tester.pump(const Duration(milliseconds: 150));
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(
|
tester.state(find.byKey(
|
||||||
const ValueKey<String>(bottomRoute),
|
const ValueKey<String?>(bottomRoute),
|
||||||
skipOffstage: false,
|
skipOffstage: false,
|
||||||
)),
|
)),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
navigator.currentState.pop();
|
navigator.currentState!.pop();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 150));
|
await tester.pump(const Duration(milliseconds: 150));
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(topRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(topRoute))),
|
||||||
topState,
|
topState,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(
|
expect(
|
||||||
tester.state(find.byKey(const ValueKey<String>(bottomRoute))),
|
tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
|
||||||
bottomState,
|
bottomState,
|
||||||
);
|
);
|
||||||
expect(find.byKey(const ValueKey<String>(topRoute)), findsNothing);
|
expect(find.byKey(const ValueKey<String?>(topRoute)), findsNothing);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1704,21 +1704,21 @@ void main() {
|
|||||||
Finder fillContainerFinder = find
|
Finder fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/')),
|
of: find.byKey(const ValueKey<String?>('/')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
expect(tester.widget<Container>(fillContainerFinder).color,
|
expect(tester.widget<Container>(fillContainerFinder).color,
|
||||||
defaultFillColor);
|
defaultFillColor);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
fillContainerFinder = find
|
fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/a')),
|
of: find.byKey(const ValueKey<String?>('/a')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
@ -1743,20 +1743,20 @@ void main() {
|
|||||||
Finder fillContainerFinder = find
|
Finder fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/')),
|
of: find.byKey(const ValueKey<String?>('/')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);
|
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);
|
||||||
|
|
||||||
navigator.currentState.pushNamed(topRoute);
|
navigator.currentState!.pushNamed(topRoute);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
fillContainerFinder = find
|
fillContainerFinder = find
|
||||||
.ancestor(
|
.ancestor(
|
||||||
matching: find.byType(Container),
|
matching: find.byType(Container),
|
||||||
of: find.byKey(const ValueKey<String>('/a')),
|
of: find.byKey(const ValueKey<String?>('/a')),
|
||||||
)
|
)
|
||||||
.last;
|
.last;
|
||||||
expect(fillContainerFinder, findsOneWidget);
|
expect(fillContainerFinder, findsOneWidget);
|
||||||
@ -1833,22 +1833,22 @@ void main() {
|
|||||||
|
|
||||||
double _getOpacity(String key, WidgetTester tester) {
|
double _getOpacity(String key, WidgetTester tester) {
|
||||||
final Finder finder = find.ancestor(
|
final Finder finder = find.ancestor(
|
||||||
of: find.byKey(ValueKey<String>(key)),
|
of: find.byKey(ValueKey<String?>(key)),
|
||||||
matching: find.byType(FadeTransition),
|
matching: find.byType(FadeTransition),
|
||||||
);
|
);
|
||||||
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
||||||
final FadeTransition transition = widget;
|
final FadeTransition transition = widget as FadeTransition;
|
||||||
return a * transition.opacity.value;
|
return a * transition.opacity.value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
double _getTranslationOffset(
|
double? _getTranslationOffset(
|
||||||
String key,
|
String key,
|
||||||
WidgetTester tester,
|
WidgetTester tester,
|
||||||
SharedAxisTransitionType transitionType,
|
SharedAxisTransitionType transitionType,
|
||||||
) {
|
) {
|
||||||
final Finder finder = find.ancestor(
|
final Finder finder = find.ancestor(
|
||||||
of: find.byKey(ValueKey<String>(key)),
|
of: find.byKey(ValueKey<String?>(key)),
|
||||||
matching: find.byType(Transform),
|
matching: find.byType(Transform),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1856,56 +1856,52 @@ double _getTranslationOffset(
|
|||||||
case SharedAxisTransitionType.horizontal:
|
case SharedAxisTransitionType.horizontal:
|
||||||
return tester.widgetList<Transform>(finder).fold<double>(0.0,
|
return tester.widgetList<Transform>(finder).fold<double>(0.0,
|
||||||
(double a, Widget widget) {
|
(double a, Widget widget) {
|
||||||
final Transform transition = widget;
|
final Transform transition = widget as Transform;
|
||||||
final Vector3 translation = transition.transform.getTranslation();
|
final Vector3 translation = transition.transform.getTranslation();
|
||||||
return a + translation.x;
|
return a + translation.x;
|
||||||
});
|
});
|
||||||
break;
|
|
||||||
case SharedAxisTransitionType.vertical:
|
case SharedAxisTransitionType.vertical:
|
||||||
return tester.widgetList<Transform>(finder).fold<double>(0.0,
|
return tester.widgetList<Transform>(finder).fold<double>(0.0,
|
||||||
(double a, Widget widget) {
|
(double a, Widget widget) {
|
||||||
final Transform transition = widget;
|
final Transform transition = widget as Transform;
|
||||||
final Vector3 translation = transition.transform.getTranslation();
|
final Vector3 translation = transition.transform.getTranslation();
|
||||||
return a + translation.y;
|
return a + translation.y;
|
||||||
});
|
});
|
||||||
break;
|
|
||||||
case SharedAxisTransitionType.scaled:
|
case SharedAxisTransitionType.scaled:
|
||||||
// SharedAxisTransitionType.scaled should not return a translation
|
// SharedAxisTransitionType.scaled should not return a translation
|
||||||
// offset.
|
// offset.
|
||||||
return null;
|
return null;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return null; // unreachable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double _getScale(String key, WidgetTester tester) {
|
double _getScale(String key, WidgetTester tester) {
|
||||||
final Finder finder = find.ancestor(
|
final Finder finder = find.ancestor(
|
||||||
of: find.byKey(ValueKey<String>(key)),
|
of: find.byKey(ValueKey<String?>(key)),
|
||||||
matching: find.byType(ScaleTransition),
|
matching: find.byType(ScaleTransition),
|
||||||
);
|
);
|
||||||
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
|
||||||
final ScaleTransition transition = widget;
|
final ScaleTransition transition = widget as ScaleTransition;
|
||||||
return a * transition.scale.value;
|
return a * transition.scale.value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TestWidget extends StatelessWidget {
|
class _TestWidget extends StatelessWidget {
|
||||||
const _TestWidget({
|
const _TestWidget({
|
||||||
this.navigatorKey,
|
required this.navigatorKey,
|
||||||
this.contentBuilder,
|
this.contentBuilder,
|
||||||
this.transitionType,
|
required this.transitionType,
|
||||||
this.fillColor,
|
this.fillColor,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Key navigatorKey;
|
final Key navigatorKey;
|
||||||
final _ContentBuilder contentBuilder;
|
final _ContentBuilder? contentBuilder;
|
||||||
final SharedAxisTransitionType transitionType;
|
final SharedAxisTransitionType transitionType;
|
||||||
final Color fillColor;
|
final Color? fillColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: navigatorKey as GlobalKey<NavigatorState>?,
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
platform: TargetPlatform.android,
|
platform: TargetPlatform.android,
|
||||||
pageTransitionsTheme: PageTransitionsTheme(
|
pageTransitionsTheme: PageTransitionsTheme(
|
||||||
@ -1922,11 +1918,11 @@ class _TestWidget extends StatelessWidget {
|
|||||||
settings: settings,
|
settings: settings,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return contentBuilder != null
|
return contentBuilder != null
|
||||||
? contentBuilder(settings)
|
? contentBuilder!(settings)
|
||||||
: Container(
|
: Container(
|
||||||
child: Center(
|
child: Center(
|
||||||
key: ValueKey<String>(settings.name),
|
key: ValueKey<String?>(settings.name),
|
||||||
child: Text(settings.name),
|
child: Text(settings.name!),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -1937,7 +1933,7 @@ class _TestWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _StatefulTestWidget extends StatefulWidget {
|
class _StatefulTestWidget extends StatefulWidget {
|
||||||
const _StatefulTestWidget({Key key, this.name}) : super(key: key);
|
const _StatefulTestWidget({Key? key, required this.name}) : super(key: key);
|
||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ function check_publish() {
|
|||||||
for package_name in "$@"; do
|
for package_name in "$@"; do
|
||||||
local dir="$REPO_DIR/packages/$package_name"
|
local dir="$REPO_DIR/packages/$package_name"
|
||||||
echo "Checking that $package_name can be published."
|
echo "Checking that $package_name can be published."
|
||||||
if (cd "$dir" && pub publish --dry-run > /dev/null); then
|
if (cd "$dir" && flutter pub publish --dry-run > /dev/null); then
|
||||||
echo "Package $package_name is able to be published."
|
echo "Package $package_name is able to be published."
|
||||||
else
|
else
|
||||||
error "Unable to publish $package_name"
|
error "Unable to publish $package_name"
|
||||||
|
Reference in New Issue
Block a user