在Flutter中实现类似App Store卡片关闭效果,可以通过组合手势识别、动画和自定义布局来实现。以下是核心实现方案:
核心实现思路
- 使用GestureDetector或Dismissible组件检测拖拽手势
- 结合Transform和AnimationController实现卡片移动和缩放
- 监听手势位置判断关闭条件
代码实现示例
import 'package:flutter/material.dart';
class AppStoreCard extends StatefulWidget {
@override
_AppStoreCardState createState() => _AppStoreCardState();
}
class _AppStoreCardState extends State<AppStoreCard>
with SingleTickerProviderStateMixin {
AnimationController _controller;
double _dragOffset = 0.0;
bool _isDragging = false;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 300),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _onPanUpdate(DragUpdateDetails details) {
setState(() {
_dragOffset += details.delta.dy;
_isDragging = true;
});
}
void _onPanEnd(DragEndDetails details) {
if (_dragOffset.abs() > 100) {
// 满足关闭条件
_controller.forward().then((_) {
// 执行关闭操作
if (mounted) {
// 移除卡片或执行其他关闭逻辑
}
});
} else {
// 复位
setState(() {
_dragOffset = 0.0;
_isDragging = false;
});
}
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanUpdate: _onPanUpdate,
onPanEnd: _onPanEnd,
child: AnimatedContainer(
duration: Duration(milliseconds: 200),
transform: Matrix4.identity()
..translate(0.0, _dragOffset)
..scale(_isDragging ? 0.95 : 1.0),
child: Card(
elevation: 8,
child: Container(
height: 200,
child: Center(child: Text('可关闭卡片')),
),
),
),
);
}
}
优化版本(使用Dismissible)
Dismissible(
key: Key('card'),
direction: DismissDirection.vertical,
onDismissed: (direction) {
// 卡片被关闭后的处理
},
background: Container(color: Colors.red),
child: Card(
child: Container(
height: 200,
child: Center(child: Text('滑动关闭卡片')),
),
),
)
关键要点
- 手势识别:使用
onPanUpdate跟踪拖拽位置
- 动画效果:通过
Transform实现位移和缩放
- 关闭阈值:设置合适的拖拽距离触发关闭
- 视觉反馈:拖拽时添加缩放效果增强用户体验
这种方法可以很好地模拟App Store卡片的流畅关闭体验,你可以根据实际需求调整动画参数和关闭逻辑。