您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

204 行
6.1 KiB

using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.rendering {
public enum RenderAnimatedSizeState {
start,
stable,
changed,
unstable
}
public class RenderAnimatedSize : RenderAligningShiftedBox {
public RenderAnimatedSize(
TickerProvider vsync = null,
TimeSpan? duration = null,
Curve curve = null,
Alignment alignment = null,
RenderBox child = null
) : base(child: child, alignment: alignment ?? Alignment.center) {
D.assert(vsync != null);
D.assert(duration != null);
curve = curve ?? Curves.linear;
_vsync = vsync;
_controller = new AnimationController(
vsync: this.vsync,
duration: duration);
_controller.addListener(() => {
if (_controller.value != _lastValue) {
markNeedsLayout();
}
});
_animation = new CurvedAnimation(
parent: _controller,
curve: curve);
}
AnimationController _controller;
CurvedAnimation _animation;
readonly SizeTween _sizeTween = new SizeTween();
bool _hasVisualOverflow;
float _lastValue;
public RenderAnimatedSizeState state {
get { return _state; }
}
RenderAnimatedSizeState _state = RenderAnimatedSizeState.start;
public TimeSpan? duration {
get { return _controller.duration; }
set {
D.assert(value != null);
if (value == _controller.duration) {
return;
}
_controller.duration = value;
}
}
public Curve curve {
get { return _animation.curve; }
set {
D.assert(value != null);
if (value == _animation.curve) {
return;
}
_animation.curve = value;
}
}
public bool isAnimating {
get { return _controller.isAnimating; }
}
public TickerProvider vsync {
get { return _vsync; }
set {
D.assert(value != null);
if (value == _vsync) {
return;
}
_vsync = value;
_controller.resync(vsync);
}
}
TickerProvider _vsync;
public override void detach() {
_controller.stop();
base.detach();
}
Size _animatedSize {
get { return _sizeTween.evaluate(_animation); }
}
protected override void performLayout() {
_lastValue = _controller.value;
_hasVisualOverflow = false;
if (child == null || constraints.isTight) {
_controller.stop();
size = _sizeTween.begin = _sizeTween.end = constraints.smallest;
_state = RenderAnimatedSizeState.start;
child?.layout(constraints);
return;
}
child.layout(constraints, parentUsesSize: true);
switch (_state) {
case RenderAnimatedSizeState.start:
_layoutStart();
break;
case RenderAnimatedSizeState.stable:
_layoutStable();
break;
case RenderAnimatedSizeState.changed:
_layoutChanged();
break;
case RenderAnimatedSizeState.unstable:
_layoutUnstable();
break;
}
size = constraints.constrain(_animatedSize);
alignChild();
if (size.width < _sizeTween.end.width ||
size.height < _sizeTween.end.height) {
_hasVisualOverflow = true;
}
}
void _restartAnimation() {
_lastValue = 0.0f;
_controller.forward(from: 0.0f);
}
void _layoutStart() {
_sizeTween.begin = _sizeTween.end = debugAdoptSize(child.size);
_state = RenderAnimatedSizeState.stable;
}
void _layoutStable() {
if (_sizeTween.end != child.size) {
_sizeTween.begin = size;
_sizeTween.end = debugAdoptSize(child.size);
_restartAnimation();
_state = RenderAnimatedSizeState.changed;
}
else if (_controller.value == _controller.upperBound) {
_sizeTween.begin = _sizeTween.end = debugAdoptSize(child.size);
}
else if (!_controller.isAnimating) {
_controller.forward();
}
}
void _layoutChanged() {
if (_sizeTween.end != child.size) {
_sizeTween.begin = _sizeTween.end = debugAdoptSize(child.size);
_restartAnimation();
_state = RenderAnimatedSizeState.unstable;
}
else {
_state = RenderAnimatedSizeState.stable;
if (!_controller.isAnimating) {
_controller.forward();
}
}
}
void _layoutUnstable() {
if (_sizeTween.end != child.size) {
_sizeTween.begin = _sizeTween.end = debugAdoptSize(child.size);
_restartAnimation();
}
else {
_controller.stop();
_state = RenderAnimatedSizeState.stable;
}
}
public override void paint(PaintingContext context, Offset offset) {
if (child != null && _hasVisualOverflow) {
Rect rect = Offset.zero & size;
context.pushClipRect(needsCompositing, offset, rect, base.paint);
}
else {
base.paint(context, offset);
}
}
}
}