同一小部件上的多种动画行为 - Flutter Getx Simple Animations
我正在尝试构建一个列表视图,其中包含具有不同动画行为的卡片,具体取决于悬停等用户交互。悬停的卡片需要放大,列表中的其余卡片需要缩小并使其不透明。 如:
查看代码:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:simple_animations/multi_tween/multi_tween.dart';
import 'package:simple_animations/simple_animations.dart';
import 'package:simple_animations/stateless_animation/custom_animation.dart';
import '../controllers/work_controller.dart';
class WorkView extends GetView<WorkController> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
flex: 1,
child: Container(color: Colors.blueGrey),
),
Expanded(
flex: 2,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
10,
(index) {
return MouseRegion(
onExit: (event) => controller.hoverIndex.value = -1,
onEnter: ((event) {
print("Setting index: $index");
controller.hoverIndex.value = index;
}),
child: AnimatedWorkCard(
index: index,
));
},
),
),
))
],
);
}
}
class AnimatedWorkCard extends StatefulWidget {
final int index;
const AnimatedWorkCard({
Key? key,
required this.index,
}) : super(key: key);
@override
State<AnimatedWorkCard> createState() => _AnimatedWorkCardState();
}
enum CardAnimationProps {
isNotHoveredOpacity,
isHoveredImgScale,
isNotHoveredTranslateX,
isHoveredTextTranslateY,
isHoveredTextOpacity,
}
class _AnimatedWorkCardState extends State<AnimatedWorkCard> {
final WorkController controller = Get.find();
var animationControl = CustomAnimationControl.play;
@override
Widget build(BuildContext context) {
return Obx(() {
var isHovered = controller.hoverIndex.value == widget.index;
if (!isHovered) {
return CustomAnimation<TimelineValue<CardAnimationProps>>(
control: animationControl,
tween: createNotHoveredTween(),
builder: (context, child, value) {
return Transform.translate(
offset: Offset(
value.get(CardAnimationProps.isNotHoveredTranslateX), 0),
child: child,
);
},
child: Card(
color: Colors.amber,
child: Container(
width: Get.width * 0.2,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Work ${widget.index}',
style: TextStyle(
fontSize: Get.width * 0.03,
),
),
ElevatedButton(
child: Text('Hovering: ${controller.hoverIndex.value}'),
onPressed: () {
Get.toNamed('/work/${widget.index}');
},
),
],
),
),
),
);
} else {
return CustomAnimation<TimelineValue<CardAnimationProps>>(
control: animationControl,
tween: createTween(controller.hoverIndex.value, widget.index),
builder: (context, child, value) {
return Transform.scale(
scale: value.get(CardAnimationProps.isHoveredImgScale),
child: child ?? Container());
},
child: Card(
color: Colors.amber,
child: Container(
width: Get.width * 0.2,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Work ${widget.index}',
style: TextStyle(
fontSize: Get.width * 0.03,
),
),
ElevatedButton(
child: Text('Hovering: ${controller.hoverIndex.value}'),
onPressed: () {
Get.toNamed('/work/${widget.index}');
},
),
],
),
),
),
);
}
});
}
createTween(int hoverIndex, int index) {
TimelineTween timelineTween = TimelineTween<CardAnimationProps>();
var scene =
timelineTween.addScene(begin: 0.seconds, end: 2000.milliseconds);
scene.animate(
CardAnimationProps.isHoveredImgScale,
tween: Tween<double>(begin: 1, end: 1.3),
);
scene.animate(
CardAnimationProps.isHoveredTextOpacity,
tween: Tween<double>(begin: 0, end: 1),
);
scene.animate(
CardAnimationProps.isHoveredTextTranslateY,
tween: Tween<double>(begin: 20, end: 0),
);
return timelineTween;
}
createNotHoveredTween() {
TimelineTween timelineTween = TimelineTween<CardAnimationProps>();
var scene =
timelineTween.addScene(begin: 0.seconds, end: 2000.milliseconds);
scene.animate(
CardAnimationProps.isNotHoveredOpacity,
tween: Tween<double>(begin: 1, end: 0.2),
);
scene.animate(
CardAnimationProps.isNotHoveredTranslateX,
tween: Tween<double>(
begin: 0,
end: 20,
),
);
return timelineTween;
}
}
控制器代码:
import 'package:get/get.dart';
class WorkController extends GetxController {
RxInt hoverIndex = (-1).obs;
@override
void onReady() {
super.onReady();
}
@override
void onClose() {}
}
但动画不流畅,只是跳跃来自各州。
知道如何使这变得更顺利或可以考虑实施任何其他方式吗?
I am trying to build a list view with cards with different animation behaviors depending on user interactions like hovering. The hovered card needs to be scaled up and the remaining cards in the list need to be scaled down and made less opaque.
Like:
View code:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:simple_animations/multi_tween/multi_tween.dart';
import 'package:simple_animations/simple_animations.dart';
import 'package:simple_animations/stateless_animation/custom_animation.dart';
import '../controllers/work_controller.dart';
class WorkView extends GetView<WorkController> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
flex: 1,
child: Container(color: Colors.blueGrey),
),
Expanded(
flex: 2,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
10,
(index) {
return MouseRegion(
onExit: (event) => controller.hoverIndex.value = -1,
onEnter: ((event) {
print("Setting index: $index");
controller.hoverIndex.value = index;
}),
child: AnimatedWorkCard(
index: index,
));
},
),
),
))
],
);
}
}
class AnimatedWorkCard extends StatefulWidget {
final int index;
const AnimatedWorkCard({
Key? key,
required this.index,
}) : super(key: key);
@override
State<AnimatedWorkCard> createState() => _AnimatedWorkCardState();
}
enum CardAnimationProps {
isNotHoveredOpacity,
isHoveredImgScale,
isNotHoveredTranslateX,
isHoveredTextTranslateY,
isHoveredTextOpacity,
}
class _AnimatedWorkCardState extends State<AnimatedWorkCard> {
final WorkController controller = Get.find();
var animationControl = CustomAnimationControl.play;
@override
Widget build(BuildContext context) {
return Obx(() {
var isHovered = controller.hoverIndex.value == widget.index;
if (!isHovered) {
return CustomAnimation<TimelineValue<CardAnimationProps>>(
control: animationControl,
tween: createNotHoveredTween(),
builder: (context, child, value) {
return Transform.translate(
offset: Offset(
value.get(CardAnimationProps.isNotHoveredTranslateX), 0),
child: child,
);
},
child: Card(
color: Colors.amber,
child: Container(
width: Get.width * 0.2,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Work ${widget.index}',
style: TextStyle(
fontSize: Get.width * 0.03,
),
),
ElevatedButton(
child: Text('Hovering: ${controller.hoverIndex.value}'),
onPressed: () {
Get.toNamed('/work/${widget.index}');
},
),
],
),
),
),
);
} else {
return CustomAnimation<TimelineValue<CardAnimationProps>>(
control: animationControl,
tween: createTween(controller.hoverIndex.value, widget.index),
builder: (context, child, value) {
return Transform.scale(
scale: value.get(CardAnimationProps.isHoveredImgScale),
child: child ?? Container());
},
child: Card(
color: Colors.amber,
child: Container(
width: Get.width * 0.2,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Work ${widget.index}',
style: TextStyle(
fontSize: Get.width * 0.03,
),
),
ElevatedButton(
child: Text('Hovering: ${controller.hoverIndex.value}'),
onPressed: () {
Get.toNamed('/work/${widget.index}');
},
),
],
),
),
),
);
}
});
}
createTween(int hoverIndex, int index) {
TimelineTween timelineTween = TimelineTween<CardAnimationProps>();
var scene =
timelineTween.addScene(begin: 0.seconds, end: 2000.milliseconds);
scene.animate(
CardAnimationProps.isHoveredImgScale,
tween: Tween<double>(begin: 1, end: 1.3),
);
scene.animate(
CardAnimationProps.isHoveredTextOpacity,
tween: Tween<double>(begin: 0, end: 1),
);
scene.animate(
CardAnimationProps.isHoveredTextTranslateY,
tween: Tween<double>(begin: 20, end: 0),
);
return timelineTween;
}
createNotHoveredTween() {
TimelineTween timelineTween = TimelineTween<CardAnimationProps>();
var scene =
timelineTween.addScene(begin: 0.seconds, end: 2000.milliseconds);
scene.animate(
CardAnimationProps.isNotHoveredOpacity,
tween: Tween<double>(begin: 1, end: 0.2),
);
scene.animate(
CardAnimationProps.isNotHoveredTranslateX,
tween: Tween<double>(
begin: 0,
end: 20,
),
);
return timelineTween;
}
}
Controller code:
import 'package:get/get.dart';
class WorkController extends GetxController {
RxInt hoverIndex = (-1).obs;
@override
void onReady() {
super.onReady();
}
@override
void onClose() {}
}
But the animation is not smooth and it's just jumping from the states.
Any idea how this can made smoother or any other way this can be thought of implementing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论