You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何实现Dismissible弹窗拖拽时背景模糊度平滑调整

问题根因
  • 你当前仅监听了用户触摸事件更新模糊度,Dismissible 松手后会执行内部自带的退场动画,这期间没有事件触发模糊度参数更新,导致模糊值停在松手时的数值,直到弹窗完全关闭才消失,过渡效果就会突兀。
最优解决方案(修改量最小)

不需要重构现有逻辑,只需要补充松手后的模糊度过渡动画即可,动画时长和 Dismissible 默认退场时长对齐即可:

  1. 首先给State类混入动画支持,并新增动画相关变量
class _YourDialogState extends State<YourDialog> with SingleTickerProviderStateMixin {
  // 原有变量
  double _percentageHeight = 1;
  double? _initialPosY;
  // 新增动画变量
  late AnimationController _blurController;
  late Animation<double> _blurAnimation;

  @override
  void initState() {
    super.initState();
    // 时长和Dismissible默认退场时长保持一致
    _blurController = AnimationController(vsync: this, duration: const Duration(milliseconds: 200));
    _blurAnimation = Tween<double>(begin: 1, end: 0).animate(CurvedAnimation(
      parent: _blurController,
      curve: Curves.easeOut,
    ))..addListener(() {
      setState(() {
        _percentageHeight = _blurAnimation.value;
      });
    });
  }

  @override
  void dispose() {
    _blurController.dispose();
    super.dispose();
  }
  // 其余原有逻辑不变
}
  1. 给Listener新增松手触发动画的回调,同时兼容用户拖拽一半取消的场景
Listener(
  // 新增松手回调
  onPointerUp: (_) {
    if (_percentageHeight < 1) {
      _blurController.forward(from: _percentageHeight);
    }
  },
  onPointerMove: (PointerMoveEvent event) {
    double percentage = 1 - (_initialPosY! - event.position.dy).abs() / _keyMyDialog.currentContext!.size!.height;
    // 拖拽回到原位时重置动画
    if (percentage >= 1) {
      percentage = 1;
      _blurController.reset();
    }
    setState(() => _percentageHeight = percentage);
  },
  // 原有onPointerDown、onPointerSignal逻辑不变
  child: Dismissible(
    // 原有Dismissible逻辑不变
  ),
)
高可控性替代方案

如果后续需要扩展更多弹窗交互,建议直接弃用Dismissible,自行通过GestureDetector+AnimationController实现拖拽和退场逻辑,全程可以实时获取弹窗偏移量,直接同步计算模糊度即可,不需要额外适配内部动画。

内容的提问来源于stack exchange,提问作者user12051965

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 00:30:03