Flutter开箱即用一站式解决方案5.0-ComDraggable悬浮拖拽

0 阅读3分钟

Flutter Chen Common

Pub Version License

🌟 简介

Flutter Chen Common 是一个功能丰富的 Flutter 通用库,为应用开发提供一站式解决方案。

  • 可定制的主题系统
  • 完整的国际化支持
  • 企业级网络请求封装
  • 企业级日志体系封装
  • N+高质量常用组件
  • 常用开发工具及扩展集合
  • 智能刷新列表解决方案
  • 全局统一各状态布局
  • 全局无需Context的Toast

特性

  • 🎨 主题系统:通过 ThemeExtension 全局配置颜色/圆角/间距等样式
  • 🌍 国际化支持:内置中英文,支持自定义文本和动态语言切换
  • 优先级覆盖:支持全局配置 + 组件级参数覆盖
  • 📱 自适应设计:完美适配 iOS/Material 设计规范
  • 🔥 企业级方案:内置日志/网络/安全等通用模块,提供开箱即用的复杂场景解决方案

🚀 快速接入

安装依赖

pubspec.yaml 中添加依赖:

dependencies:
  flutter_chen_common: 最新版本

ComDraggable 悬浮拖拽组件

ComDraggable 是一个通用的悬浮拖拽容器,适合承载悬浮按钮、调试入口、客服入口、快捷工具球等场景。

它基于以下能力实现:

  • Stack 作为悬浮层容器
  • Positioned 控制当前位置
  • GestureDetector 处理拖动手势
  • 默认开启横向吸边
  • 吸边带缓动动画,并结合释放方向让手感更自然

功能特性

  • 通用 child 容器,可承载任意 Widget
  • 默认右下角定位,使用 initialRight / initialBottom
  • 支持安全区约束
  • 支持边界留白 boundaryMargin
  • 支持拖动中视觉态 builder
  • 支持关闭拖动
  • 支持关闭吸边

ComDraggable 效果预览

快速开始

基础用法

ComDraggable(
  initialRight: 24,
  initialBottom: 120,
  childSize: const Size(62, 62),
  child: DecoratedBox(
    decoration: BoxDecoration(
      color: Colors.blue,
      shape: BoxShape.circle,
    ),
    child: Icon(Icons.chat, color: Colors.white),
  ),
)

自定义拖动中视觉反馈

ComDraggable(
  initialRight: 24,
  initialBottom: 120,
  childSize: const Size(62, 62),
  builder: (context, child, isDragging) {
    return AnimatedScale(
      scale: isDragging ? 1.06 : 1,
      duration: const Duration(milliseconds: 120),
      child: child,
    );
  },
  child: DecoratedBox(
    decoration: BoxDecoration(
      color: Colors.deepPurple,
      shape: BoxShape.circle,
    ),
    child: Icon(Icons.bug_report, color: Colors.white),
  ),
)

关闭吸边

ComDraggable(
  initialRight: 24,
  initialBottom: 120,
  snapToEdge: false,
  childSize: const Size(62, 62),
  child: YourFloatingWidget(),
)

吸边说明

默认开启 snapToEdge

组件在拖拽结束后会按以下规则吸边:

  1. 优先参考释放时的横向速度
  2. 如果释放速度不明显,则按当前位置距离最近的左右边吸附
  3. 吸边过程使用短时缓动动画,而不是直接跳边

当前只做横向吸边,纵向位置保持释放时的位置。

API

参数类型默认值说明
childWidget-悬浮内容
childSizeSize-悬浮内容占用尺寸,用于边界计算
initialRightdouble0初始右侧偏移
initialBottomdouble0初始底部偏移
draggablebooltrue是否允许拖动
snapToEdgebooltrue是否开启横向吸边
useSafeAreabooltrue是否把安全区纳入可拖拽边界
boundaryMarginEdgeInsetsEdgeInsets.zero额外边界留白
clipBehaviorClipClip.none外层 Stack 的裁剪行为
snapAnimationDurationDuration180ms吸边动画时长
snapAnimationCurveCurveCurves.easeOutCubic吸边动画曲线
onPositionChangedValueChanged<Offset>?null位置变化回调,回传 (right, bottom)
builderWidget Function(BuildContext, Widget, bool)?null自定义包装器,第三个参数表示是否正在拖动

使用建议

  • childSize 要和实际可点击区域尺寸一致,否则边界计算会偏。
  • 如果悬浮内容有阴影,建议通过 boundaryMargin 预留一点空间。
  • 如果业务需要记忆位置,可以在 onPositionChanged 里持久化最终的 (right, bottom)
  • 如果用于全局悬浮入口,建议放在页面最外层的 StackOverlay 中。