Flutter浮动视图插件flutter_floating的使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter浮动视图插件flutter_floating的使用

简介

Floating 是一个灵活且强大的悬浮窗解决方案,适用于Flutter应用。它提供了全局和单页面的悬浮窗管理机制,并支持多种自定义功能,如位置保存、滑动边界控制、日志查看等。

特性

  • 全局的悬浮窗管理机制
  • 支持各项回调监听(如移动、按下等)
  • 支持自定义是否保存悬浮窗的位置信息
  • 支持单页面及全局使用,可插入多个悬浮窗
  • 支持自定义禁止滑动区域(例如在距离顶部50到底部的区域内滑动等)
  • 完善的日志系统,可查看不同悬浮窗对应的Log
  • 支持自定义位置方向及悬浮窗的各项指标
  • 支持越界回弹、边缘自动吸附(是否吸附,吸附位置可选)、多指触摸移动、自适应屏幕旋转以及小窗口等情况
  • 自适应悬浮窗大小
  • 适配悬浮窗动画,对悬浮窗大小改变时位置进行适配
  • 代码内可更改浮窗位置

打开方式

项目迁移至 Flutter 3.0,目前使用的 SDK 是 Flutter 3.0.3,3.0 以下可能无法使用,请自行升级 Flutter SDK。

dependencies:
  flutter_floating: ^1.0.7

效果图

全局 小屏 缩放屏幕
全屏悬浮窗 小屏悬浮窗 缩放屏幕
旋转屏幕 多指滑动
旋转屏幕 多指滑动

可自由控制的日志查看

创建悬浮窗的时候通过 isShowLog 属性控制,不同的悬浮窗 Log 会通过不同 key 显示出来。

I/flutter (24648): Floating_Log 1 : 按下 X:0.0 Y:150.0
I/flutter (24648): Floating_Log 1 : 抬起 X:0.0 Y:150.0
I/flutter (24648): Floating_Log 1 : 移动 X:0.36363636363636687 Y:150.0
I/flutter (24648): Floating_Log 1 : 移动 X:0.36363636363636687 Y:149.63636363636363
I/flutter (24648): Floating_Log 1 : 移动 X:0.7272727272727337 Y:149.63636363636363
I/flutter (24648): Floating_Log 1 : 移动 X:1.0909090909091006 Y:149.27272727272725
I/flutter (24648): Floating_Log 1 : 移动 X:1.4545454545454675 Y:149.27272727272725
I/flutter (24648): Floating_Log 1 : 移动 X:1.4545454545454675 Y:148.90909090909088
I/flutter (24648): Floating_Log 1 : 移动 X:0.0 Y:145.9999999999999
I/flutter (24648): Floating_Log 1 : 移动结束 X:0.0 Y:145.9999999999999

使用方式

可选参数

/// [child] 需要悬浮的 widget
/// [slideType],可参考 [FloatingSlideType]
///
/// [top], [left], [right], [bottom] 对应 [slideType],
/// 例如设置 [slideType] 为 [FloatingSlideType.onRightAndBottom],则需要传入 [bottom] 和 [right]
///
/// [isPosCache] 启用之后当调用 [Floating.close] 重新调用 [Floating.open] 后会保持之前的位置
/// [isSnapToEdge] 是否自动吸附边缘,默认为 true ,请注意,移动默认是有透明动画的,如需要关闭透明度动画,
/// 请修改 [moveOpacity] 为 1
/// [slideTopHeight] 滑动边界控制,可滑动到顶部的距离
/// [slideBottomHeight] 滑动边界控制,可滑动到底部的距离
/// [slideStopType] 移动后回弹停靠的位置 [lideStopType]
Floating(
  Widget child, {
  FloatingSlideType slideType = FloatingSlideType.onRightAndBottom,
  double? top,
  double? left,
  double? right,
  double? bottom,
  double moveOpacity = 0.3,
  bool isPosCache = true,
  bool isShowLog = true,
  bool isSnapToEdge = true,
  this.slideTopHeight = 0,
  this.slideBottomHeight = 0,
  SlideStopType slideStopType = SlideStopType.slideStopAutoType,
})

全局悬浮窗

全局的悬浮窗通过 FloatingManager 进行管理。

  • 创建悬浮窗

    floatingOne = floatingManager.createFloating(
      "1", // key
      Floating(
        const FloatingIncrement(),
        slideType: FloatingSlideType.onLeftAndTop,
        isShowLog: false,
        slideBottomHeight: 100,
      ),
    );
    
  • 通过 FloatingManager 获取 key 对应的悬浮窗

    floatingManager.getFloating("1");
    
  • 关闭 key 对应的悬浮窗

    floatingManager.closeFloating("1");
    
  • 关闭所有悬浮窗

    floatingManager.closeAllFloating();
    

单悬浮窗创建

单悬浮窗可用于某个页面中,页面退出后关闭即可。

class CustomPage extends StatefulWidget {
  const CustomPage({Key? key}) : super(key: key);

  [@override](/user/override)
  _CustomPageState createState() => _CustomPageState();
}

class _CustomPageState extends State<CustomPage> {
  late Floating floating;

  [@override](/user/override)
  void initState() {
    super.initState();
    floating = Floating(
      const FloatingIncrement(),
      slideType: FloatingSlideType.onLeftAndTop,
      isShowLog: false,
      slideBottomHeight: 100,
    );
    floating.open();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("功能页面"),
      ),
      body: Container(),
    );
  }

  [@override](/user/override)
  void dispose() {
    floating.close();
    super.dispose();
  }
}

添加悬浮窗各项回调

var oneListener = FloatingListener()
  ..openListener = () {
    print('显示1');
  }
  ..closeListener = () {
    print('关闭1');
  }
  ..downListener = (x, y) {
    print('按下1');
  }
  ..upListener = (x, y) {
    print('抬起1');
  }
  ..moveListener = (x, y) {
    print('移动 $x  $y  1');
  }
  ..moveEndListener = (x, y) {
    print('移动结束 $x  $y  1');
  };
floatingOne.addFloatingListener(oneListener);

完整示例 Demo

以下是一个完整的示例,展示了如何在 Flutter 应用中使用 flutter_floating 插件创建和管理悬浮窗。

import 'package:flutter/material.dart';
import 'package:flutter_floating/floating.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  [@override](/user/override)
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late FloatingManager floatingManager;
  late Floating floatingOne;

  [@override](/user/override)
  void initState() {
    super.initState();
    floatingManager = FloatingManager(); // 初始化悬浮窗管理器
    createFloatingWindow(); // 创建悬浮窗
  }

  void createFloatingWindow() {
    floatingOne = floatingManager.createFloating(
      "1", // key
      Floating(
        const Icon(Icons.notifications), // 悬浮窗内容
        slideType: FloatingSlideType.onRightAndBottom, // 悬浮窗位置
        isShowLog: true, // 是否显示日志
        slideBottomHeight: 100, // 禁止滑动区域
      ),
    );

    // 添加悬浮窗回调
    var oneListener = FloatingListener()
      ..openListener = () {
        print('显示1');
      }
      ..closeListener = () {
        print('关闭1');
      }
      ..downListener = (x, y) {
        print('按下1');
      }
      ..upListener = (x, y) {
        print('抬起1');
      }
      ..moveListener = (x, y) {
        print('移动 $x  $y  1');
      }
      ..moveEndListener = (x, y) {
        print('移动结束 $x  $y  1');
      };
    floatingOne.addFloatingListener(oneListener);
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("悬浮窗示例"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () {
                floatingOne.open(); // 打开悬浮窗
              },
              child: Text("打开悬浮窗"),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                floatingOne.close(); // 关闭悬浮窗
              },
              child: Text("关闭悬浮窗"),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                floatingManager.closeAllFloating(); // 关闭所有悬浮窗
              },
              child: Text("关闭所有悬浮窗"),
            ),
          ],
        ),
      ),
    );
  }

  [@override](/user/override)
  void dispose() {
    floatingManager.closeAllFloating(); // 释放资源
    super.dispose();
  }
}

更多关于Flutter浮动视图插件flutter_floating的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter浮动视图插件flutter_floating的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,我可以为你提供一个关于如何在Flutter中使用flutter_floating插件的示例代码。flutter_floating插件允许你在Flutter应用中创建浮动视图,这些视图可以悬浮在其他内容之上,并且可以在屏幕上拖动。

首先,你需要在你的pubspec.yaml文件中添加flutter_floating依赖项:

dependencies:
  flutter:
    sdk: flutter
  flutter_floating: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖项。

接下来,你可以在你的Flutter应用中使用这个插件。以下是一个简单的示例,展示如何创建一个浮动视图:

import 'package:flutter/material.dart';
import 'package:flutter_floating/flutter_floating.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Floating Example'),
        ),
        body: FloatingWidgetExample(),
      ),
    );
  }
}

class FloatingWidgetExample extends StatefulWidget {
  @override
  _FloatingWidgetExampleState createState() => _FloatingWidgetExampleState();
}

class _FloatingWidgetExampleState extends State<FloatingWidgetExample> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        // 底层内容
        Center(
          child: Text(
            'This is the background content.',
            style: TextStyle(fontSize: 24),
          ),
        ),
        // 浮动视图
        Positioned(
          // 使用Positioned小部件来定位浮动视图
          top: 100,
          left: 100,
          child: FloatingActionButton(
            onPressed: () {
              // 点击事件
              print('Floating button clicked!');
            },
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
          // 包装在FloatingWidget中
          floatingWidget: FloatingWidget(
            // 浮动视图的配置
            dragEnabled: true,  // 允许拖动
            removeEnabled: true, // 允许移除
            removeBackgroundColor: Colors.red, // 移除按钮的背景颜色
            removeIcon: Icons.close, // 移除按钮的图标
            onRemove: () {
              // 移除浮动视图时的回调
              print('Floating widget removed!');
            },
          ),
        ),
      ],
    );
  }
}

请注意,上面的代码示例中使用了StackPositioned小部件来创建浮动视图。Positioned小部件允许你指定浮动视图在屏幕上的位置。FloatingWidget包装了FloatingActionButton,并为其提供了拖动和移除的功能。

然而,需要注意的是,flutter_floating插件的实际API和用法可能会根据版本的不同而有所变化。因此,建议查阅该插件的最新文档以获取最准确的信息和用法示例。

此外,由于flutter_floating插件可能不是官方或广泛使用的插件,因此在使用之前,请确保它符合你的需求,并检查其社区支持和维护情况。如果插件不再维护或有已知的严重问题,可能需要考虑使用其他替代方案。

回到顶部