Open container: fade through color tween (#192)

This commit is contained in:
Konstantin Dovnar
2020-10-08 01:14:48 +03:00
committed by GitHub
parent 2f62e55889
commit 2275190fe6
2 changed files with 28 additions and 8 deletions

View File

@ -83,6 +83,7 @@ class OpenContainer<T extends Object> extends StatefulWidget {
Key key, Key key,
this.closedColor = Colors.white, this.closedColor = Colors.white,
this.openColor = Colors.white, this.openColor = Colors.white,
this.middleColor,
this.closedElevation = 1.0, this.closedElevation = 1.0,
this.openElevation = 4.0, this.openElevation = 4.0,
this.closedShape = const RoundedRectangleBorder( this.closedShape = const RoundedRectangleBorder(
@ -112,9 +113,9 @@ class OpenContainer<T extends Object> extends StatefulWidget {
/// Background color of the container while it is closed. /// Background color of the container while it is closed.
/// ///
/// When the container is opened, it will first transition from this color /// When the container is opened, it will first transition from this color
/// to [Colors.white] and then transition from there to [openColor] in one /// to [middleColor] and then transition from there to [openColor] in one
/// smooth animation. When the container is closed, it will transition back to /// smooth animation. When the container is closed, it will transition back to
/// this color from [openColor] via [Colors.white]. /// this color from [openColor] via [middleColor].
/// ///
/// Defaults to [Colors.white]. /// Defaults to [Colors.white].
/// ///
@ -126,9 +127,9 @@ class OpenContainer<T extends Object> extends StatefulWidget {
/// Background color of the container while it is open. /// Background color of the container while it is open.
/// ///
/// When the container is closed, it will first transition from [closedColor] /// When the container is closed, it will first transition from [closedColor]
/// to [Colors.white] and then transition from there to this color in one /// to [middleColor] and then transition from there to this color in one
/// smooth animation. When the container is closed, it will transition back to /// smooth animation. When the container is closed, it will transition back to
/// [closedColor] from this color via [Colors.white]. /// [closedColor] from this color via [middleColor].
/// ///
/// Defaults to [Colors.white]. /// Defaults to [Colors.white].
/// ///
@ -137,6 +138,16 @@ class OpenContainer<T extends Object> extends StatefulWidget {
/// * [Material.color], which is used to implement this property. /// * [Material.color], which is used to implement this property.
final Color openColor; final Color openColor;
/// The color to use for the background color during the transition
/// with [ContainerTransitionType.fadeThrough].
///
/// Defaults to [Theme]'s [ThemeData.canvasColor].
///
/// See also:
///
/// * [Material.color], which is used to implement this property.
final Color middleColor;
/// Elevation of the container while it is closed. /// Elevation of the container while it is closed.
/// ///
/// When the container is opened, it will transition from this elevation to /// When the container is opened, it will transition from this elevation to
@ -264,12 +275,15 @@ class _OpenContainerState<T> extends State<OpenContainer<T>> {
final GlobalKey _closedBuilderKey = GlobalKey(); final GlobalKey _closedBuilderKey = GlobalKey();
Future<void> openContainer() async { Future<void> openContainer() async {
final Color middleColor =
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>(
closedColor: widget.closedColor, closedColor: widget.closedColor,
openColor: widget.openColor, openColor: widget.openColor,
middleColor: middleColor,
closedElevation: widget.closedElevation, closedElevation: widget.closedElevation,
openElevation: widget.openElevation, openElevation: widget.openElevation,
closedShape: widget.closedShape, closedShape: widget.closedShape,
@ -383,6 +397,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
_OpenContainerRoute({ _OpenContainerRoute({
@required this.closedColor, @required this.closedColor,
@required this.openColor, @required this.openColor,
@required this.middleColor,
@required double closedElevation, @required double closedElevation,
@required this.openElevation, @required this.openElevation,
@required ShapeBorder closedShape, @required ShapeBorder closedShape,
@ -417,6 +432,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
transitionType: transitionType, transitionType: transitionType,
closedColor: closedColor, closedColor: closedColor,
openColor: openColor, openColor: openColor,
middleColor: middleColor,
), ),
_closedOpacityTween = _getClosedOpacityTween(transitionType), _closedOpacityTween = _getClosedOpacityTween(transitionType),
_openOpacityTween = _getOpenOpacityTween(transitionType); _openOpacityTween = _getOpenOpacityTween(transitionType);
@ -425,6 +441,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
@required ContainerTransitionType transitionType, @required ContainerTransitionType transitionType,
@required Color closedColor, @required Color closedColor,
@required Color openColor, @required Color openColor,
@required Color middleColor,
}) { }) {
switch (transitionType) { switch (transitionType) {
case ContainerTransitionType.fade: case ContainerTransitionType.fade:
@ -448,11 +465,11 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
return _FlippableTweenSequence<Color>( return _FlippableTweenSequence<Color>(
<TweenSequenceItem<Color>>[ <TweenSequenceItem<Color>>[
TweenSequenceItem<Color>( TweenSequenceItem<Color>(
tween: ColorTween(begin: closedColor, end: Colors.white), tween: ColorTween(begin: closedColor, end: middleColor),
weight: 1 / 5, weight: 1 / 5,
), ),
TweenSequenceItem<Color>( TweenSequenceItem<Color>(
tween: ColorTween(begin: Colors.white, end: openColor), tween: ColorTween(begin: middleColor, end: openColor),
weight: 4 / 5, weight: 4 / 5,
), ),
], ],
@ -533,6 +550,7 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
final Color closedColor; final Color closedColor;
final Color openColor; final Color openColor;
final Color middleColor;
final double openElevation; final double openElevation;
final ShapeBorder openShape; final ShapeBorder openShape;
final CloseContainerBuilder closedBuilder; final CloseContainerBuilder closedBuilder;

View File

@ -364,6 +364,7 @@ void main() {
child: OpenContainer( child: OpenContainer(
closedColor: Colors.green, closedColor: Colors.green,
openColor: Colors.blue, openColor: Colors.blue,
middleColor: Colors.red,
closedElevation: 4.0, closedElevation: 4.0,
openElevation: 8.0, openElevation: 8.0,
closedShape: shape, closedShape: shape,
@ -461,7 +462,7 @@ void main() {
biggerMaterial: dataMidpoint, biggerMaterial: dataMidpoint,
tester: tester, tester: tester,
); );
expect(dataMidpoint.material.color, isNot(dataMidFadeOut.material.color)); expect(dataMidpoint.material.color, Colors.red);
expect(_getOpacity(tester, 'Open'), moreOrLessEquals(0.0)); expect(_getOpacity(tester, 'Open'), moreOrLessEquals(0.0));
expect(_getOpacity(tester, 'Closed'), moreOrLessEquals(0.0)); expect(_getOpacity(tester, 'Closed'), moreOrLessEquals(0.0));
@ -538,6 +539,7 @@ void main() {
child: OpenContainer( child: OpenContainer(
closedColor: Colors.green, closedColor: Colors.green,
openColor: Colors.blue, openColor: Colors.blue,
middleColor: Colors.red,
closedElevation: 4.0, closedElevation: 4.0,
openElevation: 8.0, openElevation: 8.0,
closedShape: shape, closedShape: shape,
@ -635,7 +637,7 @@ void main() {
biggerMaterial: dataMidFadeOut, biggerMaterial: dataMidFadeOut,
tester: tester, tester: tester,
); );
expect(dataMidpoint.material.color, isNot(dataMidFadeOut.material.color)); expect(dataMidpoint.material.color, Colors.red);
expect(_getOpacity(tester, 'Open'), moreOrLessEquals(0.0)); expect(_getOpacity(tester, 'Open'), moreOrLessEquals(0.0));
expect(_getOpacity(tester, 'Closed'), moreOrLessEquals(0.0)); expect(_getOpacity(tester, 'Closed'), moreOrLessEquals(0.0));