gpt4 book ai didi

flutter - 按下按钮时启动动画 - Flutter

转载 作者:行者123 更新时间:2023-12-05 02:09:22 24 4
gpt4 key购买 nike

我是 Flutter 的新手,我正在尝试创建一个 UI,其中有一个卡片组和一个显示的卡片。每当用户按下卡片组时,我都希望显示一张新卡片(使用带有 Positioned 小部件的翻转和移动动画)。

问题是,我无法理解每次创建小部件时如何使动画出现。

我试图让动画继续我创建的小部件的初始状态,但这似乎不起作用。

这是应用小部件树:

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 _CardState extends State<MyCard> with TickerProviderStateMixin {
AnimationController animController;
Animation flipAnimation;
Animation positionAnimation;

@override
void initState() {
super.initState();
animController = new AnimationController(
vsync: this, duration: Duration(milliseconds: 1000));
flipAnimation = Tween<double>(begin: 1.0, end: 0).animate(animController);
positionAnimation =
Tween<double>(begin: 40.0, end: 240.0).animate(animController);

animController.forward();
}

@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),
),
),
);
}
}

谢谢!

最佳答案

您可以在下面复制粘贴运行完整代码
你可以在didUpdateWidget中调用animController.reset()forward()
出于演示目的,我将动画持续时间更改为 3 秒
详情可以引用https://medium.com/sk-geek/flutter-experiment-to-trigger-animation-when-parent-setstate-84e949530b64

代码片段

@override
void didUpdateWidget(MyCard oldWidget) {
animController.reset();
animController.forward();
super.didUpdateWidget(oldWidget);
}

工作演示

enter image description here

完整代码

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),
),
),
);
}
}

关于flutter - 按下按钮时启动动画 - Flutter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59966821/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com