Mar*_*rcG 5 flutter flutter-animation
我想改变一些小部件的孩子,然后看到它动画到新孩子的高度,也有淡入淡出的过渡。
我可以用 来做到这一点AnimatedCrossFade
,但是我必须同时保留firstChild
和secondChild
,而我不能。
如果我使用AnimatedSwitcher
,它可以让我简单地改变它的孩子,但它只会动画淡入淡出,而不是大小。
这AnimatedContainer
也不起作用,因为我事先不知道孩子的大小。
是否有一些我缺少的小部件可以满足我的需求,如果没有,我怎么能在不诉诸AnimationController
s 的情况下做到这一点?
这解决了这个问题:
https://pub.dev/packages/animated_size_and_fade
它同时淡化和动画大小,而不必指定两个孩子。您还可以分别为淡入淡出和大小定义持续时间和曲线。
像这样使用它:
bool toggle=true;
Widget widget1 = ...;
Widget widget2 = ...;
AnimatedSizeAndFade(
vsync: this,
child: toggle ? widget1 : widget2,
),
Run Code Online (Sandbox Code Playgroud)
注意:如果你想使用上面的代码,请阅读文档:
“旧”和“新”子项必须具有相同的宽度,但可以具有不同的高度。
如果“新”子项与“旧”子项具有相同的小部件类型,但具有不同的参数,则AnimatedSizeAndFade
不会在它们之间进行转换,因为就框架而言,它们是相同的小部件,而现有的小部件可以使用新参数更新小部件。要强制发生转换,请设置Key
(通常是ValueKey
获取任何小部件数据,这些数据会更改您希望被视为唯一的每个子小部件上的小部件的视觉外观。
这是一个可运行的示例:
import 'package:flutter/material.dart';
import 'package:widgets/widgets.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
bool toggle;
@override
void initState() {
super.initState();
toggle = false;
}
@override
Widget build(BuildContext context) {
var toggleButton = Padding(
padding: const EdgeInsets.all(8.0),
child: MaterialButton(
child: const Text("Toggle"),
color: Colors.grey,
onPressed: () {
setState(() {
toggle = !toggle;
});
},
),
);
var widget1 = Container(
key: ValueKey("first"),
color: Colors.blue,
width: 200.0,
child: const 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.",
),
);
var widget2 = Container(
key: ValueKey("second"),
color: Colors.red,
width: 200.0,
child: const Text(
"I am ready for my closeup.",
),
);
return MaterialApp(
home: Material(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(height: 100.0),
toggleButton,
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("Some text above."),
AnimatedSizeAndFade(
vsync: this,
child: toggle ? widget1 : widget2,
fadeDuration: const Duration(milliseconds: 300),
sizeDuration: const Duration(milliseconds: 600),
),
const Text("Some text below."),
],
),
],
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
有很多方法可以实现这一目标。这只是一个例子:
class LogoApp extends StatefulWidget {
_LogoAppState createState() => _LogoAppState();
}
class _LogoAppState extends State<LogoApp> with TickerProviderStateMixin {
Animation animation;
Animation animationOpacity;
AnimationController controller;
initState() {
super.initState();
controller = AnimationController(
duration: const Duration(milliseconds: 2000), vsync: this);
final CurvedAnimation curve =
CurvedAnimation(parent: controller, curve: Curves.easeIn);
animation = Tween(begin: 0.0, end: 300.0).animate(curve);
animationOpacity = Tween(begin: 0.0, end: 1.0).animate(curve);
controller.forward();
}
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: controller,
builder: (context, widget) {
return Opacity(
opacity: animationOpacity.value,
child: Container(
margin: EdgeInsets.symmetric(vertical: 10.0),
height: animation.value,
width: animation.value,
child: FlutterLogo(),
),
);
},
);
}
dispose() {
controller.dispose();
super.dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: Material(child: Center(child: LogoApp())));
}
Run Code Online (Sandbox Code Playgroud)
参考这个文档 Flutter Animations
更新
class LogoApp extends StatefulWidget {
_LogoAppState createState() => _LogoAppState();
}
class _LogoAppState extends State<LogoApp> with TickerProviderStateMixin {
Animation controllerAnimation;
AnimationController controller;
initState() {
super.initState();
controller = AnimationController(
duration: const Duration(milliseconds: 1000), vsync: this);
final CurvedAnimation curve =
CurvedAnimation(parent: controller, curve: Curves.easeIn);
controllerAnimation = Tween(begin: 0.0, end: 1.0).animate(curve);
controller.forward();
}
bool isSelected = false;
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
AnimatedSwitcher(
duration: Duration(seconds: 10),//it is ignored
child: isSelected
? Container(
width: 200.0,
height: 200.0,
child: FlutterLogo(
colors: Colors.red,
),
)
: Container(
width: 200.0,
height: 200.0,
child: FlutterLogo(
colors: Colors.blue,
)),
transitionBuilder: defaultTransitionBuilder,
),
MaterialButton(
child: Text("Texting"),
onPressed: () {
if (controller.isCompleted) {
controller.reset();
}
controller.forward();
setState(() {
isSelected = !isSelected;
});
},
)
],
);
}
Widget defaultTransitionBuilder(Widget child, Animation<double> animation) {
return AnimatedBuilder(
animation: controller,
builder: (context, widget) {
return Opacity(
opacity: controllerAnimation.value,
child: ScaleTransition(
scale: controllerAnimation,
child: widget,
),
);
},
child: child,
);
}
dispose() {
controller.dispose();
super.dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7110 次 |
最近记录: |