搜索插件、代码仓与 APP 分类

draggable_float_widget 封面
插件详情v0.1.0

draggable_float_widget

这是一个可拖动且浮动的 Flutter 小部件,可以通过 ScrollView 的滚动事件来控制其可见性。

AndroidiOSWebmacOSWindowsLinux
近 30 天下载
17.7万
喜欢数
116
Pub 分数
150

安装插件

flutter pub add draggable_float_widget

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

一个 Flutter 包,提供了一个可拖动的浮动小部件,能够根据滚动事件自动显示或隐藏。非常适合创建交互式 UI 元素,例如浮动操作按钮或自定义叠加层,这些元素会跟随用户的滚动行为。该小部件可以在屏幕上自由移动,并根据滚动方向和在 ScrollView 中的位置自动调整可见性。支持所有主要平台,包括 Android、iOS、Web、macOS、Windows 和 Linux。

适合场景

  • 可滚动列表中的浮动操作按钮
  • 可响应滚动的交互叠加层
  • 自定义可拖动的UI组件
  • 增强移动应用导航
  • Web应用程序中的动态UI元素

主要特点

  • 可拖动定位
  • 滚动触发的可见性控制
  • 跨平台兼容性
  • 拖动时的平滑动画
  • 可配置的显示/隐藏阈值
  • 支持多个平台目标

适合对象

  • 开发滚动感知用户界面的开发者
  • 需要动态浮动元素的移动和网页应用
  • 实现基于手势交互的设计人员
  • 具有复杂叠加需求的应用程序
  • 面向多平台部署的团队

使用建议

  • 大型列表可能需要性能调优
  • 复杂的滚动行为可能需要自定义可见性逻辑
  • 有限的内置样式选项
  • 不适合静态浮动元素
  • 在嵌套滚动视图中需要谨慎处理

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

draggable_float_widget

This is a draggable and floating Flutter widget, which can control its visibility through the scrolling event of ScrollView.

Usage

To use this plugin, add draggable_float_widget as a dependency in your pubspec.yaml file.

constructor
  • the constructor of component

    DraggableFloatWidget({
      Key? key,
      this.width = defaultWidgetWidth,
      this.height = defaultWidgetHeight,
      this.eventStreamController,
      this.config = const DraggableFloatWidgetBaseConfig(),
      required this.child,
      this.onTap,
    }) : super(key: key);
    
  • special field instructions

    property description default
    eventStreamController The [StreamController] of [OperateEvent] null
    config the base config of [DraggableFloatWidget] DraggableFloatWidgetBaseConfig()
  • the base config of component

    DraggableFloatWidgetBaseConfig({
      this.isFullScreen = true,
      this.appBarHeight = kToolbarHeight,
      this.initPositionXInLeft = true,
      this.initPositionYInTop = true,
      this.initPositionYMarginBorder = 0,
      this.borderLeft = defaultBorderWidth,
      this.borderRight = defaultBorderWidth,
      this.borderTop = defaultBorderWidth,
      this.borderTopContainTopBar = false,
      this.borderBottom = defaultBorderWidth,
      this.exposedPartWidthWhenHidden = defaultExposedPartWidthWhenHidden,
      this.animDuration = const Duration(milliseconds: 300),
      this.delayShowDuration = const Duration(milliseconds: 500),
      this.debug = false,
    });
    
example
  • the first, add scroll listener

    ⚠️Ignore this step if the component is not affected by ScrollView scrolling, and you don't need to pass an StreamController instance into the instance.

    NotificationListener(
      onNotification: (notification) {
        if (notification is ScrollStartNotification) {
          eventStreamController.add(OperateEvent.OPERATE_HIDE);
        } else if (notification is ScrollEndNotification) {
          eventStreamController.add(OperateEvent.OPERATE_SHOW);
        }
        return true;
      },
      child: ListView(...),
    )
    
  • the first way: stack mode

    Stack(
      children: [
        listView,
        DraggableFloatWidget(
          child: child,
          eventStreamController: eventStreamController,
          config: DraggableFloatWidgetBaseConfig(
            isFullScreen: false,
            initPositionYInTop: false,
            initPositionYMarginBorder: 50,
            borderBottom: navigatorBarHeight + defaultBorderWidth,
          ),
          onTap: () => print("Drag onTap!"),
        )
      ],
    )
    

    stack mode

  • the second way: overlay mode

    _overlayEntry = OverlayEntry(builder: (context) {
      return DraggableFloatWidget(
        child: widget.child,
        eventStreamController: widget.eventStreamController,
        config: DraggableFloatWidgetBaseConfig(
          initPositionYInTop: false,
          initPositionYMarginBorder: 50,
          borderTopContainTopBar: true,
          borderBottom: widget.navigatorBarHeight + defaultBorderWidth,
        ),
        onTap: () => print("Drag onTap!"),
      );
    });
    
    /// Warning: context cannot be the context of MaterialApp
    Overlay.of(context)?.insert(_overlayEntry!);
    

    overlay mode

Contributions

If you encounter any problem or the library is missing a feature feel free to open an issue. Feel free to fork, improve the package and make pull request.

License

MIT

所属分类

源码仓库

使用此插件的项目