您作为用户的经历多次点击没有动画的按钮,因为您不知道它是否确实发送了您请求的操作?如果按钮有一个轻微的动画告诉你它实际被点击了,你就不需要做了多次同样的事情。
什么是动画?我们为什么要使用它们?
在为您的应用程序创建良好的用户体验时,添加制作精良且流畅的动画至关重要。它们作为用户行为的视觉反馈,也可以提供互动和保证的意义。
动画按钮就是本文的内容,特别是我们将构建一个小型弹跳动画,当用户单击按钮时会触发该动画。
首先,按钮布局
按钮布局基于一个简单的容器,其中心有一个文本小部件。
Widget get _animatedButtonUI => Container(
height: 100,
width: 250,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
boxShadow: [ shadow ],
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFFA7BFE8),
Color(0xFF6190E8),
],
),
),
child: Center(
child: Text(
'tap!',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
);
我们来看看动画
我们需要使用setState()和dispose()函数,因此我们将扩展StatefulWidget。
class AnimatedButton extends StatefulWidget {
@override
_AnimatedButtonState createState() => _AnimatedButtonState();
}
class _AnimatedButtonState extends State<AnimatedButton> {
@override
Widget build(BuildContext context) {
return Container();
}
Widget get _animatedButtonUI => ...
}
我们都准备开始制作动画了。
让我们实现SingleTickerProviderStateMixin并定义我们创建动画所需的两个属性。
class _AnimatedButtonState extends State<AnimatedButton> with SingleTickerProviderStateMixin {
double _scale;
AnimationController _controller;
@override
Widget build(BuildContext context) {
return Container();
}
...
}
现在是时候通过重写initState()来初始化我的_controller并通过覆盖dispose()函数来处理它
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 200),
lowerBound: 0.0,
upperBound: 0.1,
)
..addListener(() { setState(() {});});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
接下来,我们定义了两个函数,一个用于按下按钮,另一个用于释放按钮时,前者将告诉我们的控制器继续前进,而后者则反过来
void _onTapDown(TapDownDetails details) {
_controller.forward();
}
void _onTapUp(TapUpDetails details) {
_controller.reverse();
}
最后,在我们的构建函数中,我们设置了scale变量,让GestureDetector处理tapDown和tapUp属性,然后使用Transform小部件进行缩放
@override
Widget build(BuildContext context) {
_scale = 1 - _controller.value;
return GestureDetector(
onTapDown: _onTapDown,
onTapUp: _onTapUp,
child: Transform.scale(
scale: _scale,
child: _animatedButtonUI,
),
);
}
这是最终的结果
结论
这是一篇关于如何创建简单而有效的动画的快速文章,我希望这将有助于您改进应用程序用户体验。
全部代码
import 'package:flutter/material.dart';
class AnimatedButton extends StatefulWidget {
@override
_AnimatedButtonState createState() => _AnimatedButtonState();
}
class _AnimatedButtonState extends State<AnimatedButton>
with SingleTickerProviderStateMixin {
double _scale;
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 200),
lowerBound: 0.0,
upperBound: 0.1,
)..addListener(() {
setState(() {});
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _onTapDown(TapDownDetails details) {
_controller.forward();
}
void _onTapUp(TapUpDetails details) {
_controller.reverse();
}
@override
Widget build(BuildContext context) {
_scale = 1 - _controller.value;
return GestureDetector(
onTapDown: _onTapDown,
onTapUp: _onTapUp,
child: Transform.scale(
scale: _scale,
child: _animatedButtonUI,
),
);
}
Widget get _animatedButtonUI => Container(
height: 100,
width: 250,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
boxShadow: [
BoxShadow(
color: Color(0x80000000),
blurRadius: 30.0,
offset: Offset(0.0, 30.0),
),
],
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFFA7BFE8),
Color(0xFF6190E8),
],
),
),
child: Center(
child: Text(
'tap!',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
);
}