监听 Animation flutter 中的位置变化
listen for the position changes inside Animation flutter
有没有在动画当前运行(未完成或取消)时监听子控件位置的变化?
例如
我们有这个变量:
GlobalKey globalKey= GlobalKey();
bool isAnimated =false;
我需要监听此 AnimatedContainer 中目标小部件的位置:
InkWell(
onTap:() => setState(() {isAnimated=!isAnimated};) ,
child: AnimatedContainer(
duration: Duration(milliseconds: 1000),
width: 200,
height: isAnimated?100:40,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(height: 10,),
//the target widget
SizedBox(
key: globalKey,
)
],)
),
)
例如,当 AnimatedContainer 的高度达到 70 时,它会根据目标小部件的位置确认我要做一些事情。
您的具体要求不清楚。根据 'do something to a target widget' 的含义,您可能需要选择不同的方法。但是,如果您想向动画添加侦听器或对当前动画值做出反应,最好使用 AnimatedBuilder。我提供了一个可能对您的案例有所帮助的基本示例。
class MyAnimatedWidget extends StatefulWidget {
const MyAnimatedWidget({
Key? key,
}) : super(key: key);
@override
State<MyAnimatedWidget> createState() => _MyAnimatedWidgetState();
}
class _MyAnimatedWidgetState extends State<MyAnimatedWidget>
with TickerProviderStateMixin {
late final AnimationController _controller;
late Animation _animation;
GlobalKey globalKey = GlobalKey();
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1000),
);
_controller.addListener(() {
//also possible to listen for changes with a listener
});
_animation = CurveTween(curve: Curves.easeOut).animate(_controller);
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return InkWell(
onTap: () {},
child: Container(
width: 200,
height: _containerHeightBuilder(_controller.value),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
const SizedBox(
height: 10,
),
//the target widget
SizedBox(
//or do something here with the current animation value
key: globalKey,
)
],
)),
);
});
}
double _containerHeightBuilder(double animationValue) {
const double containerAnimationTarget = 60;
const double containerBaseHeight = 40;
const double thresholdHeight = 70;
double currentHeight =
containerBaseHeight + (containerAnimationTarget * animationValue);
if (currentHeight == thresholdHeight) {
//do something here
}
return currentHeight;
}
}
有没有在动画当前运行(未完成或取消)时监听子控件位置的变化? 例如 我们有这个变量:
GlobalKey globalKey= GlobalKey();
bool isAnimated =false;
我需要监听此 AnimatedContainer 中目标小部件的位置:
InkWell(
onTap:() => setState(() {isAnimated=!isAnimated};) ,
child: AnimatedContainer(
duration: Duration(milliseconds: 1000),
width: 200,
height: isAnimated?100:40,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(height: 10,),
//the target widget
SizedBox(
key: globalKey,
)
],)
),
)
例如,当 AnimatedContainer 的高度达到 70 时,它会根据目标小部件的位置确认我要做一些事情。
您的具体要求不清楚。根据 'do something to a target widget' 的含义,您可能需要选择不同的方法。但是,如果您想向动画添加侦听器或对当前动画值做出反应,最好使用 AnimatedBuilder。我提供了一个可能对您的案例有所帮助的基本示例。
class MyAnimatedWidget extends StatefulWidget {
const MyAnimatedWidget({
Key? key,
}) : super(key: key);
@override
State<MyAnimatedWidget> createState() => _MyAnimatedWidgetState();
}
class _MyAnimatedWidgetState extends State<MyAnimatedWidget>
with TickerProviderStateMixin {
late final AnimationController _controller;
late Animation _animation;
GlobalKey globalKey = GlobalKey();
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1000),
);
_controller.addListener(() {
//also possible to listen for changes with a listener
});
_animation = CurveTween(curve: Curves.easeOut).animate(_controller);
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return InkWell(
onTap: () {},
child: Container(
width: 200,
height: _containerHeightBuilder(_controller.value),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
const SizedBox(
height: 10,
),
//the target widget
SizedBox(
//or do something here with the current animation value
key: globalKey,
)
],
)),
);
});
}
double _containerHeightBuilder(double animationValue) {
const double containerAnimationTarget = 60;
const double containerBaseHeight = 40;
const double thresholdHeight = 70;
double currentHeight =
containerBaseHeight + (containerAnimationTarget * animationValue);
if (currentHeight == thresholdHeight) {
//do something here
}
return currentHeight;
}
}