Flutter:多个动画 onTapDown
Flutter: Multiple animations onTapDown
如何让同一个动画在不同的地方同时播放。目前,每当我点击屏幕时,动画就会在那个地方开始播放 3 秒,但如果我再次按下另一个地方,动画就会跳到那个地方,但我希望它让旧动画结束。所以如果你按五次,屏幕上应该有五个动画,不像现在一次只播放一个。
这是我的代码。
class HomePage extends StatefulWidget{
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
double posx = -100.0;
double posy = -100.0;
void onLongPressMoveUpdate(BuildContext context, LongPressMoveUpdateDetails details)
{
final RenderBox box = context.findRenderObject();
final Offset localOffset = box.globalToLocal(details.globalPosition);
var tempName = "tryck";
setState(() {
_tryckanimation = tempName;
posx = localOffset.dx;
posy = localOffset.dy;
});
}
void onTapDown(BuildContext context, TapDownDetails details)
{
final RenderBox box = context.findRenderObject();
final Offset localOffset = box.globalToLocal(details.globalPosition);
var tempName = "tryck";
setState(() {
_tryckanimation = tempName;
posx = localOffset.dx;
posy = localOffset.dy;
});
}
void onTapUp(BuildContext context, TapUpDetails details)
{
final RenderBox box = context.findRenderObject();
final Offset localOffset = box.globalToLocal(details.globalPosition);
var tempName = "tryck";
Future.delayed(const Duration(milliseconds: 3000), () {
setState(() {
setState(() {
_tryckanimation = tempName;
posx = -100.0;
posy = -100.0;
});
});
});
}
new GestureDetector(
onTapDown: (TapDownDetails details) => onTapDown(context, details),
onTapUp: (TapUpDetails details) => onTapUp(context, details),
onLongPressMoveUpdate: (LongPressMoveUpdateDetails details) => onLongPressMoveUpdate(context, details),
child: new Stack(fit: StackFit.expand, children: <Widget>[
new Container(color: Colors.transparent,
),
new Positioned(
height: 100.0,
width: 100.0,
child: FlareActor(
"assets/images/tryck2.flr",
animation: _tryckanimation
),
left: posx -50.0,
top: posy- 50.0,
),
您必须为所有动画小部件设置相同的AnimationController
。
试试这个
import 'dart:math';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
body: HomePage(),
),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
final tappedPositions = <Offset>[];
AnimationController _animationController;
@override
void initState() {
_animationController = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
);
_animationController.repeat();
super.initState();
}
final x = const CircularProgressIndicator();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("App Bar"),
),
body: Stack(
children: <Widget>[
GestureDetector(
onTapUp: (tabDetails) {
setState(() {
tappedPositions.add(tabDetails.localPosition);
});
},
child: Container(
color: Colors.white,
),
),
for (final position in tappedPositions)
Positioned(
top: position.dy,
left: position.dx,
child: MyAnimatedWidget(
animation: _animationController,
),
),
],
),
);
}
}
class MyAnimatedWidget extends StatelessWidget {
final Animation animation;
const MyAnimatedWidget({Key key, this.animation}) : super(key: key);
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: animation,
child: Icon(
Icons.phone,
color: Colors.blue,
size: 30.0,
),
builder: (context, child) {
return Transform(
alignment: Alignment.center,
transform: Matrix4.identity()
..translate(animation.value)
..rotateY(pi * 2 * animation.value),
child: child,
);
},
);
}
}
如何让同一个动画在不同的地方同时播放。目前,每当我点击屏幕时,动画就会在那个地方开始播放 3 秒,但如果我再次按下另一个地方,动画就会跳到那个地方,但我希望它让旧动画结束。所以如果你按五次,屏幕上应该有五个动画,不像现在一次只播放一个。
这是我的代码。
class HomePage extends StatefulWidget{
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
double posx = -100.0;
double posy = -100.0;
void onLongPressMoveUpdate(BuildContext context, LongPressMoveUpdateDetails details)
{
final RenderBox box = context.findRenderObject();
final Offset localOffset = box.globalToLocal(details.globalPosition);
var tempName = "tryck";
setState(() {
_tryckanimation = tempName;
posx = localOffset.dx;
posy = localOffset.dy;
});
}
void onTapDown(BuildContext context, TapDownDetails details)
{
final RenderBox box = context.findRenderObject();
final Offset localOffset = box.globalToLocal(details.globalPosition);
var tempName = "tryck";
setState(() {
_tryckanimation = tempName;
posx = localOffset.dx;
posy = localOffset.dy;
});
}
void onTapUp(BuildContext context, TapUpDetails details)
{
final RenderBox box = context.findRenderObject();
final Offset localOffset = box.globalToLocal(details.globalPosition);
var tempName = "tryck";
Future.delayed(const Duration(milliseconds: 3000), () {
setState(() {
setState(() {
_tryckanimation = tempName;
posx = -100.0;
posy = -100.0;
});
});
});
}
new GestureDetector(
onTapDown: (TapDownDetails details) => onTapDown(context, details),
onTapUp: (TapUpDetails details) => onTapUp(context, details),
onLongPressMoveUpdate: (LongPressMoveUpdateDetails details) => onLongPressMoveUpdate(context, details),
child: new Stack(fit: StackFit.expand, children: <Widget>[
new Container(color: Colors.transparent,
),
new Positioned(
height: 100.0,
width: 100.0,
child: FlareActor(
"assets/images/tryck2.flr",
animation: _tryckanimation
),
left: posx -50.0,
top: posy- 50.0,
),
您必须为所有动画小部件设置相同的AnimationController
。
试试这个
import 'dart:math';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
body: HomePage(),
),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
final tappedPositions = <Offset>[];
AnimationController _animationController;
@override
void initState() {
_animationController = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
);
_animationController.repeat();
super.initState();
}
final x = const CircularProgressIndicator();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("App Bar"),
),
body: Stack(
children: <Widget>[
GestureDetector(
onTapUp: (tabDetails) {
setState(() {
tappedPositions.add(tabDetails.localPosition);
});
},
child: Container(
color: Colors.white,
),
),
for (final position in tappedPositions)
Positioned(
top: position.dy,
left: position.dx,
child: MyAnimatedWidget(
animation: _animationController,
),
),
],
),
);
}
}
class MyAnimatedWidget extends StatelessWidget {
final Animation animation;
const MyAnimatedWidget({Key key, this.animation}) : super(key: key);
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: animation,
child: Icon(
Icons.phone,
color: Colors.blue,
size: 30.0,
),
builder: (context, child) {
return Transform(
alignment: Alignment.center,
transform: Matrix4.identity()
..translate(animation.value)
..rotateY(pi * 2 * animation.value),
child: child,
);
},
);
}
}