1.先看动效:

shake_animation.gif
2.代码:
import 'package:flutter/material.dart';
class FCShakeScreen extends StatefulWidget {
static const routeName = '/shake';
@override
_FCShakeScreenState createState() => _FCShakeScreenState();
}
class _FCShakeScreenState extends State<FCShakeScreen> with TickerProviderStateMixin {
TextEditingController _controller;
// 创建动效控制器
AnimationController _shakeXAnimController;
Animation _shakeXAnim;
int _maxShakeCount = 3; // 最大抖动次数
int _shakeNumber = 0; // 记录抖动次数 (forward() + reverse() 算一次动画完成)
@override
void initState() {
super.initState();
// 利用水平反复移动实现动效; xMin = 0.0 xMax = 10.0
_shakeXAnimController = AnimationController(vsync: this, duration: Duration(milliseconds: 150));
_shakeXAnim = Tween(begin: 0.0, end: 10.0).animate(_shakeXAnimController);
// 监听动画
_shakeXAnimController.addListener(() {
setState(() {});
});
// 监听动画状态
_shakeXAnimController.addStatusListener((status) {
if (status == AnimationStatus.completed) { // 一次forward() 完成
_shakeNumber+=1;
_shakeXAnimController.reverse();
} else if (status == AnimationStatus.dismissed) { // forward() + reverse() 来回整个动画 完成
_shakeXAnimController.reset(); // 重置
if (_shakeNumber < _maxShakeCount) {
_shakeXAnimController.forward();
} else {
_shakeNumber = 0;
}
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Shake')
),
body: Column(
children: [
SizedBox(height: 80),
Transform.translate( // 这里包裹个水平移动
offset: Offset(_shakeXAnim.value, 0), // 设置动画值 0.0 -- 10.0
child: Container(
margin: EdgeInsets.only(left: 30, right: 30),
decoration: BoxDecoration(
color: Colors.yellow[800],
borderRadius: BorderRadius.circular(30),
border: Border.all(color: Color(0x80fafafa))
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Icon(Icons.phone_android, size: 30, color: Colors.white),
),
// 竖线
Container(width: 1.0, height: 26, color: Color(0xaafafafa)),
SizedBox(width: 10),
Expanded(
child: TextField(
controller: _controller,
decoration: InputDecoration(
hintText: "请输入11位手机号码",
hintStyle: TextStyle(color: Colors.white),
border: InputBorder.none,
),
),
),
],
),
),
),
SizedBox(height: 35),
FlatButton(
color: Colors.red[600],
child: Text("开始"),
onPressed: () => _shakeXAnimController.forward()
)
],
),
);
}
}
网友评论