import 'dart:ffi';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
Animation<double> _animation;
Animation<Offset> _slideAnimation;
@override
void initState() {
super.initState();
_animationController = new AnimationController(
duration: Duration(milliseconds: 3000), vsync: this);
_animationController.addListener(() {
setState(() {});
});
_animation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
parent: _animationController, curve: Curves.bounceInOut));
_slideAnimation = Tween(begin: Offset(0, -0.5), end: Offset(0, 0)).animate(
CurvedAnimation(
parent: _animationController, curve: Curves.bounceInOut));
_animationController.forward();
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
body: Stack(
children: [
// 第一部分 底部的内容
buildBottomMenu(),
// 第二部分 按钮
buildButtonFunction(),
// 第二部分 文字
buildText(),
],
));
}
buildBottomMenu() {
return Positioned(
height: 62,
bottom: 0,
left: 0,
right: 0,
child: Container(
child: CustomPaint(
painter: CustomMyPainter(_animation.value),
),
),
);
}
buildText() {
return Positioned(
left: 0,
right: 0,
top: 120,
child: Text(
'hello world',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
color: Colors.deepOrangeAccent,
fontWeight: FontWeight.bold),
));
}
buildButtonFunction() {
return Align(
alignment: Alignment.bottomCenter,
// 让按钮动起来
child: SlideTransition(
position: _slideAnimation,
// 解决水波纹背景超出按钮区域
child: Container(
margin: EdgeInsets.only(bottom: 22),
child: Ink(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(30)),
),
child: InkWell(
borderRadius: BorderRadius.all(Radius.circular(30)),
child: Container(
width: 62,
height: 62,
// decoration: BoxDecoration(
// color: Colors.blue,
// borderRadius: BorderRadius.all(Radius.circular(30))),
child: Icon(
Icons.add,
color: Colors.white,
),
),
onTap: (){
if(_animationController.isAnimating){
return;
}
if(_animationController.isCompleted){
_animationController.reverse();
}else {
_animationController.reset();
_animationController.forward();
}
},
),
),
),
),
);
}
}
class CustomMyPainter extends CustomPainter {
double progress;
CustomMyPainter(this.progress);
// 创建一个画笔
Paint _paint = new Paint()..color = Colors.orangeAccent;
@override
void paint(Canvas canvas, Size size) {
double width = size.width;
double height = size.height;
Path _path = new Path();
_path.moveTo(0, 0);
// 开始画三阶曲线
_path.lineTo(width / 4 + width / 8 * progress, 0);
double x1 = width / 4 + width / 8 * progress;
double y1 = 64 * progress;
double x2 = width / 2 + width / 8;
double y2 = 64 * progress;
double x3 = width / 2 + width * 2 / 8 - width / 8 * progress;
double y3 = 0;
_path.cubicTo(x1, y1, x2, y2, x3, y3);
_path.lineTo(width, 0);
_path.lineTo(width, height);
_path.lineTo(0, height);
_path.close();
canvas.drawPath(_path, _paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}