Flutter 按下按钮时启动动画-颤振
我是个新手,我正在尝试创建一个UI,其中有一个卡片组和一张显示的卡片。每当用户按下卡片组时,我都希望显示一张新卡片(使用翻转和移动的动画和定位小部件) 问题是,我不明白如何在每次创建小部件时都显示动画 我试图使动画进入我创建的小部件的初始状态,但这似乎不起作用 这是应用程序小部件树:Flutter 按下按钮时启动动画-颤振,flutter,Flutter,我是个新手,我正在尝试创建一个UI,其中有一个卡片组和一张显示的卡片。每当用户按下卡片组时,我都希望显示一张新卡片(使用翻转和移动的动画和定位小部件) 问题是,我不明白如何在每次创建小部件时都显示动画 我试图使动画进入我创建的小部件的初始状态,但这似乎不起作用 这是应用程序小部件树: class _DeckState extends State<Deck> with TickerProviderStateMixin { List<MyCard> _cards= <
class _DeckState extends State<Deck> with TickerProviderStateMixin {
List<MyCard> _cards= <MyCard>[];
@override
void initState() {
super.initState();
_cards.insert(0, MyCard());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("NLP Deck"),
),
body: Stack(
alignment: Alignment.center,
children: <Widget>[
Container(),
_cards[0],
Positioned(
top: 40.0,
child: GestureDetector(
onTap: PressedDeck,
child: Container(
width: 100.0,
height: 128.0,
decoration: BoxDecoration(color: Colors.brown),
),
),
),
],
),
);
}
void PressedDeck() {
setState(() {
_cards.insert(0, new MyCard());
});
}
}
class\u DeckState使用TickerProviderStateMixin扩展状态{
列表_卡=[];
@凌驾
void initState(){
super.initState();
_插入(0,MyCard());
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“NLP组”),
),
主体:堆栈(
对齐:对齐.center,
儿童:[
容器(),
_卡片[0],
定位(
排名:40.0,
儿童:手势检测器(
onTap:按Deck,
子:容器(
宽度:100.0,
高度:128.0,
装饰:盒子装饰(颜色:颜色.棕色),
),
),
),
],
),
);
}
void PressedDeck(){
设置状态(){
_插入(0,新MyCard());
});
}
}
这是我创建的卡片小部件(使用容器表示卡片和卡片组):
class\u CardState使用TickerProviderStateMixin扩展状态{
动画控制器;
动画动画;
动画定位动画;
@凌驾
void initState(){
super.initState();
animController=新的AnimationController(
vsync:this,duration:duration(毫秒:1000));
flipAnimation=Tween(开始:1.0,结束:0)。动画制作(动画控制器);
位置动画=
吐温(开始:40.0,结束:240.0)。动画(动画控制器);
animController.forward();
}
@凌驾
小部件构建(构建上下文){
返回位置转换(
位置:positionAnimation,
翻转:翻转动画,
);
}
@凌驾
无效处置(){
animController.dispose();
super.dispose();
}
}
类PositionTransition扩展了AnimatedWidget{
位置转换({
@所需动画位置,
@需要这个.flip,
}):super(可收听:位置);
最终动画翻转;
@凌驾
小部件构建(构建上下文){
最终位置=super.listenable作为动画;
返回定位(
顶部:位置。值,
孩子:变换(
对齐:分馏loffset.center,
变换:Matrix4.rotationX(math.pi*flip.value),
子项:flip.value>=0.5
?容器(
宽度:100,
身高:128,
装饰:盒子装饰(颜色:深橙色),
)
:容器(
宽度:100,
身高:128,
装饰:盒子装饰(颜色:颜色。琥珀色),
),
),
);
}
}
谢谢 您可以在下面复制粘贴运行完整代码
您可以在
didUpdateWidget
中调用animController.reset()
和forward()
出于演示目的,我将动画持续时间更改为3秒有关详细信息,请参考 代码片段
@override
void didUpdateWidget(MyCard oldWidget) {
animController.reset();
animController.forward();
super.didUpdateWidget(oldWidget);
}
工作演示
完整代码
import 'package:flutter/material.dart';
import 'dart:math' as math;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Deck(),
);
}
}
class Deck extends StatefulWidget {
@override
_DeckState createState() => _DeckState();
}
class _DeckState extends State<Deck> with TickerProviderStateMixin {
List<MyCard> _cards = <MyCard>[];
@override
void initState() {
super.initState();
_cards.insert(0, MyCard());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("NLP Deck"),
),
body: Stack(
alignment: Alignment.center,
children: <Widget>[
Container(),
_cards[0],
Positioned(
top: 40.0,
child: GestureDetector(
onTap: PressedDeck,
child: Container(
width: 100.0,
height: 128.0,
decoration: BoxDecoration(color: Colors.brown),
),
),
),
],
),
);
}
void PressedDeck() {
print("PressedDeck");
setState(() {
_cards.insert(0, new MyCard());
});
print("cards length ${_cards.length}");
}
}
class MyCard extends StatefulWidget {
@override
_MyCardState createState() => _MyCardState();
}
class _MyCardState extends State<MyCard> with TickerProviderStateMixin {
AnimationController animController;
Animation flipAnimation;
Animation positionAnimation;
@override
void initState() {
print("My card init State");
super.initState();
animController =
new AnimationController(vsync: this, duration: Duration(seconds: 3));
flipAnimation = Tween<double>(begin: 1.0, end: 0).animate(animController);
positionAnimation =
Tween<double>(begin: 40.0, end: 240.0).animate(animController);
animController.forward();
}
@override
void didUpdateWidget(MyCard oldWidget) {
animController.reset();
animController.forward();
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return PositionTransition(
position: positionAnimation,
flip: flipAnimation,
);
}
@override
void dispose() {
animController.dispose();
super.dispose();
}
}
class PositionTransition extends AnimatedWidget {
PositionTransition({
@required Animation<double> position,
@required this.flip,
}) : super(listenable: position);
final Animation<double> flip;
@override
Widget build(BuildContext context) {
final position = super.listenable as Animation<double>;
return Positioned(
top: position.value,
child: Transform(
alignment: FractionalOffset.center,
transform: Matrix4.rotationX(math.pi * flip.value),
child: flip.value >= 0.5
? Container(
width: 100,
height: 128,
decoration: BoxDecoration(color: Colors.deepOrange),
)
: Container(
width: 100,
height: 128,
decoration: BoxDecoration(color: Colors.amber),
),
),
);
}
}
导入“包装:颤振/材料.省道”;
导入'dart:math'作为数学;
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
首页:Deck(),
);
}
}
类组扩展了StatefulWidget{
@凌驾
_DeckState createState();
}
类_DeckState使用TickerProviderStateMixin扩展状态{
列表_卡=[];
@凌驾
void initState(){
super.initState();
_插入(0,MyCard());
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“NLP组”),
),
主体:堆栈(
对齐:对齐.center,
儿童:[
容器(),
_卡片[0],
定位(
排名:40.0,
儿童:手势检测器(
onTap:按Deck,
子:容器(
宽度:100.0,
高度:128.0,
装饰:盒子装饰(颜色:颜色.棕色),
),
),
),
],
),
);
}
void PressedDeck(){
打印(“按下复选框”);
设置状态(){
_插入(0,新MyCard());
});
打印(“卡片长度${u cards.length}”);
}
}
类MyCard扩展了StatefulWidget{
@凌驾
_MyCardState createState()=>\u MyCardState();
}
类_MyCardState使用TickerProviderStateMixin扩展状态{
动画控制器;
动画动画;
动画定位动画;
@凌驾
void initState(){
打印(“我的卡初始状态”);
super.initState();
动物控制器=
新的AnimationController(vsync:this,duration:duration(秒数:3));
flipAnimation=Tween(开始:1.0,结束:0)。动画制作(动画控制器);
位置动画=
吐温(开始:40.0,结束:240.0)。动画(动画控制器);
animController.forward();
}
@凌驾
void didUpdateWidget(MyCard oldWidget){
animController.reset();
animController.forward();
super.didUpdateWidget(oldWidget);
}
@凌驾
小部件构建(构建上下文){
返回位置转换(
位置:positionAnimation,
翻转:翻转动画,
);
}
@凌驾
无效处置(){
animController.dispose();
super.dispose();
}
}
类PositionTransition扩展了AnimatedWidget{
import 'package:flutter/material.dart';
import 'dart:math' as math;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Deck(),
);
}
}
class Deck extends StatefulWidget {
@override
_DeckState createState() => _DeckState();
}
class _DeckState extends State<Deck> with TickerProviderStateMixin {
List<MyCard> _cards = <MyCard>[];
@override
void initState() {
super.initState();
_cards.insert(0, MyCard());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("NLP Deck"),
),
body: Stack(
alignment: Alignment.center,
children: <Widget>[
Container(),
_cards[0],
Positioned(
top: 40.0,
child: GestureDetector(
onTap: PressedDeck,
child: Container(
width: 100.0,
height: 128.0,
decoration: BoxDecoration(color: Colors.brown),
),
),
),
],
),
);
}
void PressedDeck() {
print("PressedDeck");
setState(() {
_cards.insert(0, new MyCard());
});
print("cards length ${_cards.length}");
}
}
class MyCard extends StatefulWidget {
@override
_MyCardState createState() => _MyCardState();
}
class _MyCardState extends State<MyCard> with TickerProviderStateMixin {
AnimationController animController;
Animation flipAnimation;
Animation positionAnimation;
@override
void initState() {
print("My card init State");
super.initState();
animController =
new AnimationController(vsync: this, duration: Duration(seconds: 3));
flipAnimation = Tween<double>(begin: 1.0, end: 0).animate(animController);
positionAnimation =
Tween<double>(begin: 40.0, end: 240.0).animate(animController);
animController.forward();
}
@override
void didUpdateWidget(MyCard oldWidget) {
animController.reset();
animController.forward();
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return PositionTransition(
position: positionAnimation,
flip: flipAnimation,
);
}
@override
void dispose() {
animController.dispose();
super.dispose();
}
}
class PositionTransition extends AnimatedWidget {
PositionTransition({
@required Animation<double> position,
@required this.flip,
}) : super(listenable: position);
final Animation<double> flip;
@override
Widget build(BuildContext context) {
final position = super.listenable as Animation<double>;
return Positioned(
top: position.value,
child: Transform(
alignment: FractionalOffset.center,
transform: Matrix4.rotationX(math.pi * flip.value),
child: flip.value >= 0.5
? Container(
width: 100,
height: 128,
decoration: BoxDecoration(color: Colors.deepOrange),
)
: Container(
width: 100,
height: 128,
decoration: BoxDecoration(color: Colors.amber),
),
),
);
}
}