import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(home: PhysicsCardDragDemo()));
}
class PhysicsCardDragDemo extends StatelessWidget {
const PhysicsCardDragDemo({super.key});
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(),
body: DraggableCard(
child: Container(
width: size.width * 0.8,
height: size.height * 0.8 / 3,
child: Card(
child: ListTile(title: Text("海龟汤"), subtitle: Text("汤面")),
),
),
), // FlutterLogo FlutterLogo(size: 64)
);
}
}
// 一个支持拖拽的卡片
class DraggableCard extends StatefulWidget {
const DraggableCard({required this.child, super.key});
final Widget child;
@override
State<DraggableCard> createState() => _DraggableCardState();
}
class _DraggableCardState extends State<DraggableCard>
with SingleTickerProviderStateMixin {
Alignment _dragAlignment = Alignment.center; // 卡片的对齐方式
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return GestureDetector(
// 当用户按下时,停止动画
onPanDown: (details) {},
// 当用户拖动时,更新卡片位置
onPanUpdate: (details) {
setState(() {
Alignment next =
_dragAlignment +
Alignment(
0, //details.delta.dx / (size.width / 2),
details.delta.dy / (size.height / 2),
);
// 限制拖动范围在 [-0.8, 0.8]
_dragAlignment = Alignment(
0, //next.x.clamp(-0.8, 0.8),
next.y.clamp(-0.8, 0.8),
);
});
},
onPanEnd: (details) {},
child: Align(alignment: _dragAlignment, child: widget.child),
);
}
}
效果: