Commit f7d493b6 authored by Hixie's avatar Hixie

SizeObserver crusade: Remove EnterExitTransition

...and friends.
parent 240e499b
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'basic.dart';
import 'framework.dart';
class SmoothlyResizingOverflowBox extends StatefulComponent {
SmoothlyResizingOverflowBox({
Key key,
this.child,
this.size,
this.duration,
this.curve: Curves.linear
}) : super(key: key) {
assert(duration != null);
assert(curve != null);
}
final Widget child;
final Size size;
final Duration duration;
final Curve curve;
_SmoothlyResizingOverflowBoxState createState() => new _SmoothlyResizingOverflowBoxState();
}
class _SmoothlyResizingOverflowBoxState extends State<SmoothlyResizingOverflowBox> {
SizeTween _sizeTween;
CurveTween _curveTween;
Animation<Size> _size;
AnimationController _sizeController;
void initState() {
super.initState();
_sizeController = new AnimationController(duration: config.duration);
_sizeTween = new SizeTween(begin: config.size);
_curveTween = new CurveTween(curve: config.curve);
_size = _sizeTween.chain(_curveTween).animate(_sizeController)
..addListener(() {
setState(() {});
});
}
void didUpdateConfig(SmoothlyResizingOverflowBox oldConfig) {
bool needsAnimation = false;
if (config.size != oldConfig.size) {
_sizeTween
..begin = _size.value
..end = config.size;
needsAnimation = true;
}
_sizeController.duration = config.duration;
_curveTween.curve = config.curve;
if (needsAnimation) {
_sizeController
..value = 0.0
..forward();
}
}
void dispose() {
_sizeController.stop();
super.dispose();
}
Widget build(BuildContext context) {
return new SizedOverflowBox(
size: _size.value,
child: config.child
);
}
}
class _Entry {
_Entry({
this.child,
this.enterController,
this.enterTransition
});
final Widget child;
final AnimationController enterController;
final Widget enterTransition;
Size childSize = Size.zero;
AnimationController exitController;
Widget exitTransition;
Widget get currentTransition => exitTransition ?? enterTransition;
void dispose() {
enterController?.stop();
exitController?.stop();
}
}
typedef Widget TransitionBuilderCallback(Animation<double> animation, Widget child);
Widget _identityTransition(Animation<double> animation, Widget child) => child;
class EnterExitTransition extends StatefulComponent {
EnterExitTransition({
Key key,
this.child,
this.duration,
this.curve: Curves.linear,
this.onEnter: _identityTransition,
this.onExit: _identityTransition
}) : super(key: key) {
assert(child != null);
assert(duration != null);
assert(curve != null);
assert(onEnter != null);
assert(onExit != null);
}
final Widget child;
final Duration duration;
final Curve curve;
final TransitionBuilderCallback onEnter;
final TransitionBuilderCallback onExit;
_EnterExitTransitionState createState() => new _EnterExitTransitionState();
}
class _EnterExitTransitionState extends State<EnterExitTransition> {
final List<_Entry> _entries = new List<_Entry>();
void initState() {
super.initState();
_entries.add(_createEnterTransition());
}
_Entry _createEnterTransition() {
AnimationController enterController = new AnimationController(duration: config.duration)..forward();
return new _Entry(
child: config.child,
enterController: enterController,
enterTransition: config.onEnter(enterController, new KeyedSubtree(
key: new GlobalKey(),
child: config.child
))
);
}
Future _createExitTransition(_Entry entry) async {
AnimationController exitController = new AnimationController(duration: config.duration);
entry
..exitController = exitController
..exitTransition = config.onExit(exitController, entry.enterTransition);
await exitController.forward();
if (!mounted)
return;
setState(() {
_entries.remove(entry);
});
}
void didUpdateConfig(EnterExitTransition oldConfig) {
if (config.child.key != oldConfig.child.key) {
_createExitTransition(_entries.last);
_entries.add(_createEnterTransition());
}
}
void dispose() {
for (_Entry entry in new List<_Entry>.from(_entries))
entry.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return new SmoothlyResizingOverflowBox(
size: _entries.last.childSize,
duration: config.duration,
curve: config.curve,
child: new Stack(
children: _entries.map((_Entry entry) {
return new SizeObserver(
key: new ObjectKey(entry),
onSizeChanged: (Size newSize) {
setState(() {
entry.childSize = newSize;
});
},
child: entry.currentTransition
);
}).toList()
)
);
}
}
......@@ -14,7 +14,6 @@ export 'src/widgets/child_view.dart';
export 'src/widgets/dismissable.dart';
export 'src/widgets/drag_target.dart';
export 'src/widgets/editable.dart';
export 'src/widgets/enter_exit_transition.dart';
export 'src/widgets/focus.dart';
export 'src/widgets/framework.dart';
export 'src/widgets/gesture_detector.dart';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment