Flutter:加载页面时自动启动的动画



只是想知道是否有人能帮我。我确实试过自己解决这个问题,但我是Flutter的新手,似乎可以让这个问题继续下去。我有一些Flutter代码(根据下面的链接(,它创建了一个带有波纹动画的页面。它几乎非常适合我想要做的事情,但是,动画是通过用户需要按下的浮动ActionButton激活的。有人能不能修改一下这个代码,让动画在页面加载时自动运行?我试过了。。。我真的这么做了,但我做不到。我也看了其他的例子,但无法把它们全部融合在一起。

这是代码:https://gist.github.com/MarcinusX/6925808a813e1067c52539068c9978f2

提前干杯并感谢大家。。。

下面是一个完整的工作示例。我很快就把它拼凑起来了,所以这可能不是最好的解决方案。但基本上发生的是,它在开始时使用了一个简单的bool值设置为false-

然后,一旦动画触发,就会将其设置回false。我还添加了一个计时器,这样对用户来说就不会那么刺耳了,希望这能让他们更容易理解自己在用户界面中的位置。如果你不喜欢它,你可以把它去掉。


import 'dart:async';
import 'package:flutter/material.dart';
import 'package:rect_getter/rect_getter.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fab overlay transition',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final Duration animationDuration = Duration(milliseconds: 300);
final Duration delay = Duration(milliseconds: 300);
GlobalKey rectGetterKey = RectGetter.createGlobalKey();
Rect rect;
// Handle time
Timer timer;
@override
void initState() {
// Timer starts here, this is called before the widget tree is built
timer = Timer(Duration(seconds: 1), () => setState(() {}));
super.initState();
}
// Disposes of timer - this ensures the timer is properly cancelled when this page is pulled from the widget tree
@override
void dispose() {
if (timer != null) timer.cancel();
super.dispose();
}

// This makes sure the animation only runs once
bool onTapHandler = false;
@override
Widget build(BuildContext context) {
// I moved your functions down here but it doesn't matter where they go in this case I don't think
void _goToNextPage() {
Navigator.of(context).push(FadeRouteBuilder(page: NewPage())).then((_) => setState(() => rect = null));
}
void onTap() async {
setState(() => rect = RectGetter.getRectFromKey(rectGetterKey));
if (rect != null)
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() => rect = rect.inflate(1.3 * MediaQuery.of(context).size.longestSide));
Future.delayed(animationDuration + delay, _goToNextPage);
});
}
/// Here is where the magic happens
/// This makes sure both the timer is finished and the that the flag hasn't 
/// been tripped yet. After the [onTapHandler] is set to true it won't run again
if (!timer.isActive && !onTapHandler) {
onTap();
onTapHandler = true;
}
return Stack(
children: <Widget>[
Scaffold(
appBar: AppBar(title: Text('Fab overlay transition')),
body: Center(child: Text('This is first page')),
floatingActionButton: RectGetter(
key: rectGetterKey,
child: FloatingActionButton(
onPressed: onTap,
child: Icon(Icons.mail_outline),
),
),
),
_ripple(),
],
);
}
Widget _ripple() {
if (rect == null) {
return Container();
}
return AnimatedPositioned(
duration: animationDuration,
left: rect.left,
right: MediaQuery.of(context).size.width - rect.right,
top: rect.top,
bottom: MediaQuery.of(context).size.height - rect.bottom,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blue,
),
),
);
}
}
class FadeRouteBuilder<T> extends PageRouteBuilder<T> {
final Widget page;
FadeRouteBuilder({@required this.page})
: super(
pageBuilder: (context, animation1, animation2) => page,
transitionsBuilder: (context, animation1, animation2, child) {
return FadeTransition(opacity: animation1, child: child);
},
);
}
class NewPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('NewPage'),
),
);
}
}

最新更新