FadeTransition 和 AnimatedOpacity 彼此不同步
FadeTransition and AnimatedOpacity are not in sync with each other
最小可重现代码:
static const Duration _duration = Duration(seconds: 5);
static const Curve _curve = Curves.fastOutSlowIn;
AnimationController _controller;
bool _flag = false;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: _duration);
}
@override
Widget build(BuildContext context) {
final box = Container(color: Colors.orange, width: 100, height: 100);
return Scaffold(
body: Column(
children: [
FadeTransition(
opacity: CurvedAnimation(parent: _controller, curve: _curve),
child: box,
),
SizedBox(height: 20),
AnimatedOpacity(
curve: _curve,
duration: _duration,
opacity: _flag ? 1 : 0,
child: box,
),
SizedBox(height: 20),
RaisedButton(
onPressed: () {
setState(() {
_flag = !_flag;
if (_flag) {
_controller.forward();
} else {
_controller.reverse();
}
});
},
child: Text(_flag ? 'Hide' : 'Show'),
),
],
),
);
}
输出:
如您所见,两个动画彼此不同步。我对 FadeTransition
和 AnimatedOpacity
使用相同的 Curve
和 Duration
。但是,如果删除 curve
,则动画同步。那么,我在这里做错了什么?
当您调用 _controller.reverse() 时,FadeTransition 使用反向曲线,但 AnimatedOpacity 使用相同的曲线。您可以添加 FlippedCurve 小部件来修复它。
而你不等到结束就停止动画,controller.reverse,将从停止点开始向相反的方向移动。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
static const Duration _duration = Duration(seconds: 5);
static const Curve _curve = Curves.fastOutSlowIn;
AnimationController _controller;
bool isShowing = false;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: _duration);
}
@override
Widget build(BuildContext context) {
final box = Container(color: Colors.orange, width: 100, height: 100);
return Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FadeTransition(
opacity: CurvedAnimation(parent: _controller, curve: _curve),
child: box,
),
SizedBox(height: 20),
AnimatedOpacity(
curve: isShowing ? _curve : FlippedCurve(_curve),
duration: _duration,
opacity: isShowing ? 1 : 0,
child: box,
),
SizedBox(height: 20),
RaisedButton(
onPressed: () {
setState(() {
if (isShowing) {
_controller.reverse();
} else {
_controller.forward();
}
isShowing = !isShowing;
});
},
child: Text(isShowing ? 'Hide' : 'Show'),
),
AnimatedBuilder(
builder: (_, __) {
return Text(
_controller.value.toString(),
style: TextStyle(
color: Colors.white,
),
);
},
animation: _controller)
],
),
),
);
}
}
我错过了 reverseCurve
参数。
FadeTransition(
opacity: CurvedAnimation(
parent: _controller,
curve: _curve,
reverseCurve: _curve, // Solved the problem.
),
child: box,
)
最小可重现代码:
static const Duration _duration = Duration(seconds: 5);
static const Curve _curve = Curves.fastOutSlowIn;
AnimationController _controller;
bool _flag = false;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: _duration);
}
@override
Widget build(BuildContext context) {
final box = Container(color: Colors.orange, width: 100, height: 100);
return Scaffold(
body: Column(
children: [
FadeTransition(
opacity: CurvedAnimation(parent: _controller, curve: _curve),
child: box,
),
SizedBox(height: 20),
AnimatedOpacity(
curve: _curve,
duration: _duration,
opacity: _flag ? 1 : 0,
child: box,
),
SizedBox(height: 20),
RaisedButton(
onPressed: () {
setState(() {
_flag = !_flag;
if (_flag) {
_controller.forward();
} else {
_controller.reverse();
}
});
},
child: Text(_flag ? 'Hide' : 'Show'),
),
],
),
);
}
输出:
如您所见,两个动画彼此不同步。我对 FadeTransition
和 AnimatedOpacity
使用相同的 Curve
和 Duration
。但是,如果删除 curve
,则动画同步。那么,我在这里做错了什么?
当您调用 _controller.reverse() 时,FadeTransition 使用反向曲线,但 AnimatedOpacity 使用相同的曲线。您可以添加 FlippedCurve 小部件来修复它。
而你不等到结束就停止动画,controller.reverse,将从停止点开始向相反的方向移动。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
static const Duration _duration = Duration(seconds: 5);
static const Curve _curve = Curves.fastOutSlowIn;
AnimationController _controller;
bool isShowing = false;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: _duration);
}
@override
Widget build(BuildContext context) {
final box = Container(color: Colors.orange, width: 100, height: 100);
return Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FadeTransition(
opacity: CurvedAnimation(parent: _controller, curve: _curve),
child: box,
),
SizedBox(height: 20),
AnimatedOpacity(
curve: isShowing ? _curve : FlippedCurve(_curve),
duration: _duration,
opacity: isShowing ? 1 : 0,
child: box,
),
SizedBox(height: 20),
RaisedButton(
onPressed: () {
setState(() {
if (isShowing) {
_controller.reverse();
} else {
_controller.forward();
}
isShowing = !isShowing;
});
},
child: Text(isShowing ? 'Hide' : 'Show'),
),
AnimatedBuilder(
builder: (_, __) {
return Text(
_controller.value.toString(),
style: TextStyle(
color: Colors.white,
),
);
},
animation: _controller)
],
),
),
);
}
}
我错过了 reverseCurve
参数。
FadeTransition(
opacity: CurvedAnimation(
parent: _controller,
curve: _curve,
reverseCurve: _curve, // Solved the problem.
),
child: box,
)