max*_*ax 12 flutter flutter-animation
我从https://medium.com/flutter-community/flutter-working-with-animatedsize-35253ff8f16a得到以下代码
它正在使用 AnimatedSize,但动画仅在容器扩展时才有效,而在它逃避时无效。这是默认行为吗?我想在扩展和尖叫的同时制作动画。
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
double _height = 80.0;
double _width = 80.0;
var _color = Colors.blue;
bool _resized = false;
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
AnimatedSize(
curve: Curves.easeIn,
vsync: this,
duration: new Duration(seconds: 1),
child: new GestureDetector(
onTap: () {
setState(() {
if (_resized) {
_resized = false;
_color = Colors.blue;
_height = 80.0;
_width = 80.0;
} else {
_resized = true;
_color = Colors.blue;
_height = 320.0;
_width = 320.0;
}
});
},
child: new Container(
width: _width,
height: _height,
color: _color,
),
),
),
],
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
在使用文本、列表或其他大小可变的小部件时,AnimatedContainer 并不是一个真正的选项,因为它不允许宽度或高度为 null。它也不会让您指定对齐方式。
相反,我使用带有动画控制器的 ClipRect 修复了这个问题。在下面的动画中,您可以看到收盘反弹中线左侧的“laboris”一词。这表明文本在容器关闭期间居中,只需将眼睛放在“laboris”上即可。
我创建了一个 AnimatedClipRect 小部件类,您可以轻松实现自己。您可以指定对齐方式、曲线、持续时间以及是否需要水平和/或垂直动画。现在它假设您只想完全关闭或打开它:
class AnimatedClipRect extends StatefulWidget {
@override
_AnimatedClipRectState createState() => _AnimatedClipRectState();
final Widget child;
final bool open;
final bool horizontalAnimation;
final bool verticalAnimation;
final Alignment alignment;
final Duration duration;
final Duration reverseDuration;
final Curve curve;
final Curve reverseCurve;
///The behavior of the controller when [AccessibilityFeatures.disableAnimations] is true.
final AnimationBehavior animationBehavior;
AnimatedClipRect({
this.child,
this.open,
this.horizontalAnimation = true,
this.verticalAnimation = true,
this.alignment = Alignment.center,
this.duration,
this.reverseDuration,
this.curve = Curves.linear,
this.reverseCurve,
this.animationBehavior = AnimationBehavior.normal,
});
}
class _AnimatedClipRectState extends State<AnimatedClipRect> with TickerProviderStateMixin {
AnimationController _animationController;
Animation _animation;
@override
void initState() {
_animationController = AnimationController(
duration: widget.duration ?? const Duration(milliseconds: 500),
reverseDuration: widget.reverseDuration ?? (widget.duration ?? const Duration(milliseconds: 500)),
vsync: this,
value: widget.open ? 1.0 : 0.0,
animationBehavior: widget.animationBehavior);
_animation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
parent: _animationController,
curve: widget.curve,
reverseCurve: widget.reverseCurve ?? widget.curve,
));
super.initState();
}
@override
Widget build(BuildContext context) {
widget.open ? _animationController.forward() : _animationController.reverse();
return ClipRect(
child: AnimatedBuilder(
animation: _animationController,
builder: (_, child) {
return Align(
alignment: widget.alignment,
heightFactor: widget.verticalAnimation ? _animation.value : 1.0,
widthFactor: widget.horizontalAnimation ? _animation.value : 1.0,
child: child,
);
},
child: widget.child,
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
基本用法示例,将您想要动画的任何内容放入其子项中:
// declare bool _open somewhere
Column(
children: <Widget>[
AnimatedClipRect(
open: _open,
horizontalAnimation: false,
verticalAnimation: true,
alignment: Alignment.center,
duration: Duration(milliseconds: 1000),
curve: Curves.bounceOut,
reverseCurve: Curves.bounceIn,
child: Container(
color: Colors.lightGreenAccent,
padding: EdgeInsets.all(8),
child: Text(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'),
),
),
RaisedButton(
child: Text("open/close"),
onPressed: () {
setState(() => _open ^= true);
}),
],
)
Run Code Online (Sandbox Code Playgroud)
如您所见,您所要做的就是更改 _open 并执行 setState((){}) 以触发动画。
AnimatedContainer是您正在寻找的不需要的AnimatedSize。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
double _height = 80.0;
double _width = 80.0;
var _color = Colors.blue;
bool _resized = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GestureDetector(
onTap: () {
setState(() {
if (_resized) {
_resized = false;
_color = Colors.blue;
_height = 80.0;
_width = 80.0;
} else {
_resized = true;
_color = Colors.blue;
_height = 320.0;
_width = 320.0;
}
});
},
child: AnimatedContainer(
duration: Duration(seconds: 1),
width: _width,
height: _height,
color: _color,
),
),
],
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您需要,AnimatedSize您可以添加一个以颜色作为AnimatedSize父容器的新容器。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
double _height = 320.0;
double _width = 320.0;
var _color = Colors.blue;
bool _resized = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: GestureDetector(
onTap: () {
setState(() {
if (_resized) {
_resized = false;
_color = Colors.blue;
_height = 80.0;
_width = 80.0;
} else {
_resized = true;
_color = Colors.blue;
_height = 320.0;
_width = 320.0;
}
});
},
child: Container(
color: _color,
child: AnimatedSize(
curve: Curves.easeIn,
vsync: this,
duration: Duration(seconds: 1),
child: Container(
width: _width,
height: _height,
),
),
),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4769 次 |
| 最近记录: |