Files
bluetooth_low_energy/example/lib/widgets/flip_card.dart
iAMD 6bc1a364fb Android 平台开发 (#1)
* 修复 UUID 创建失败的问题

* 移除 scanning 属性

* 临时提交

* CentralManager 开发 & 示例项目开发

* CentralManager 开发 & 示例项目开发

* android 插件生命周期监听

* 修改 API

* 示例程序开发

* 修改字体,添加 API,解决后台问题

* Central#connect API

* 蓝牙连接部分开发

* 蓝牙连接部分开发

* 解决一些问题

* 解决一些问题

* Connect API 优化

* 添加 API

* example 开发

* API 基本完成

* 消息重命名

* API 修改,Android 实现

* 删除多余代码

* 删除多余文件

* 解决 descriptor 自动生成报错的问题

* 还原 Kotlin 版本,广播处理代码迁移至 dart 端

* Kotlin 版本升至 1.5.20

* 解决特征值通知没有在主线程触发的问题,优化代码

* 引入哈希值,避免对象销毁后继续使用

* 使用下拉刷新代替搜索按钮

* 解决由于热重载和蓝牙关闭产生的问题

* 更新插件信息

* 更新 README 和 CHANGELOG

* 更新许可证

* 添加注释

* 添加注释,central 拆分
2021-07-01 17:35:54 +08:00

107 lines
2.8 KiB
Dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class FlipCard extends StatefulWidget {
final Widget? front;
final Widget? back;
const FlipCard({
Key? key,
@required this.front,
@required this.back,
}) : assert(front != null),
assert(back != null),
super(key: key);
@override
_FlipCardState createState() => _FlipCardState();
}
class _FlipCardState extends State<FlipCard> with TickerProviderStateMixin {
final ValueNotifier<double> angle;
late AnimationController animationController;
late Animation<double> frontAnimation;
late Animation<double> backAnimation;
_FlipCardState() : angle = ValueNotifier(0.0);
bool isFront = true;
bool hasHalf = false;
@override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 1000),
);
animationController.addListener(() {
if (animationController.value > 0.5) {
if (hasHalf == false) {
isFront = !isFront;
}
hasHalf = true;
}
setState(() {});
});
animationController.addStatusListener((status) {
if (status == AnimationStatus.completed) {
hasHalf = false;
}
});
frontAnimation = Tween(begin: 0.0, end: 0.5).animate(
CurvedAnimation(
parent: animationController,
curve: Interval(0.0, 0.5, curve: Curves.easeIn),
),
);
backAnimation = Tween(begin: 1.5, end: 2.0).animate(CurvedAnimation(
parent: animationController,
curve: Interval(0.5, 1.0, curve: Curves.easeOut)));
}
void animate() {
animationController.stop();
animationController.value = 0;
animationController.forward();
}
@override
void dispose() {
super.dispose();
animationController.dispose();
}
@override
Widget build(BuildContext context) {
if (animationController.status == AnimationStatus.forward) {
if (hasHalf == true) {
angle.value = backAnimation.value;
} else {
angle.value = frontAnimation.value;
}
}
return GestureDetector(
onHorizontalDragUpdate: (details) {
print(details.delta);
angle.value += 0.01;
},
child: Container(
child: ValueListenableBuilder(
valueListenable: angle,
builder: (BuildContext context, double angle, Widget? child) {
return Transform(
transform: Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateY(angle),
alignment: Alignment.center,
child: IndexedStack(
index: isFront ? 0 : 1,
children: <Widget>[widget.front!, widget.back!],
),
);
},
),
),
);
}
}