flutter线性动画
flutter动画本质就是自动生成一个线性的值,生成的间隔 和时间 控制动画的效果,
官网动画直通车这里面有教你写几个简单的小栗子
可以使用Tween来配置动画以生成不同的范围或数据类型的值,比如:
final Tween doubleTween = new Tween<double>(begin: -200.0, end: 0.0);
Tween对象不存储任何状态。相反,它提供了evaluate(Animation animation)方法将映射函数应用于动画当前值。 Animation对象的当前值可以通过value()方法取到。evaluate函数还执行一些其它处理,例如分别确保在动画值为0.0和1.0时返回开始和结束状态。
controller = AnimationController(
duration: const Duration(milliseconds: 1000), vsync: this);
curve = new CurvedAnimation(parent: controller, curve: Curves.easeInSine);
animation = Tween<double>(begin: st, end: ed).animate(curve);
animation.addListener((){
setState(() {
});
print(animation.value);
}) ;
也就是说Tween的.animate方法,传给他动画控制器和线性会返回一个Animation对象。
vsync: this动画的不在当前屏幕时,就不需要消耗不必要的资源
curve可以自定义 也可以用官网写好的常用线性效果
这有个点击旋转的例子,可以参考:
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_animation/demo/animation.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 Animation',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
//AnimatedWidget(基类)中会自动调用addListener()和setState()。
class AnimatedBox extends AnimatedWidget {
Widget build(BuildContext context) {
final Animation<double> animation = listenable;
return Center(
child: Text('s'),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class LinearSales {
final int year;
final int sales;
LinearSales(this.year, this.sales);
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
static double st = 0.0;
static double ed = 0.0;
double an = 0.0;
DragDownDetails point;
// static final _tween = new Tween<double>(begin: st, end: ed);
Animation doubleTween;
AnimationController controller;
Animation<double> animation;
Animation curve;
initState() {
super.initState();
controller = AnimationController(
duration: const Duration(milliseconds: 1000), vsync: this);
curve = new CurvedAnimation(parent: controller, curve: Curves.easeInSine);
animation = Tween<double>(begin: st, end: ed).animate(curve);
animation.addListener((){
setState(() {
});
}) ;
}
//传度数返回角度
angle(double angle) {
return (math.pi / 180) * angle;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('en'),
),
body: GestureDetector(
child: Transform.rotate(
angle: angle(animation.value),
child: Charts.create(),
),
onPanUpdate: (details) {
// double x = details.localPosition.dx;
// double y = details.localPosition.dy;
// setState(() {
// //两点坐标与中点的(180,350)夹角
// an = math.atan2(x-180,350-y)/math.pi*180;
// });
},
onPanDown: (details) {
point = details;
print(point);
setState(() {
ed = ed + 45;
animation = Tween<double>(begin: st, end: ed).animate(curve);
controller.reset();
controller.forward();
st = ed;
});
},
));
}
dispose() {
controller.dispose();
super.dispose();
}
}
class Charts extends StatelessWidget {
final List<charts.Series> seriesList;
Charts(this.seriesList);
factory Charts.create() {
return Charts(_createSampleData());
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return charts.PieChart(seriesList,
animate: false,
defaultRenderer: new charts.ArcRendererConfig(arcRendererDecorators: [
new charts.ArcLabelDecorator(
labelPosition: charts.ArcLabelPosition.outside)
]));
}
static List<charts.Series<DataRow, String>> _createSampleData() {
final data = [
new DataRow("1", "A", 123),
new DataRow("3", "B", 322),
new DataRow("4", "C", 322),
new DataRow("5", "D", 322)
];
return [
new charts.Series<DataRow, String>(
id: "serId",
// keyFn: (DataRow dr, _) => dr.id,
domainFn: (DataRow dr, _) => dr.label,
measureFn: (DataRow dr, _) => dr.value,
data: data)
];
}
}
class DataRow {
final String id;
final String label;
final double value;
DataRow(this.id, this.label, this.value);
}