Flutter滑动面板插件flutter_slidable_panel的使用

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

Flutter滑动面板插件 flutter_slidable_panel 的使用

flutter_slidable_panel 是一个高性能的可滑动面板插件,支持在不同位置显示操作按钮,并且可以在面板打开时展开操作按钮。本文将详细介绍如何使用这个插件。

特性

  1. 当面板关闭或解除时,不会绘制和布局任何操作按钮。
  2. 操作按钮的动画(如展开/折叠特定操作)会被限制在一定范围内,不会导致整个 SlidablePanel 重新布局和重新绘制。
  3. 使用 SlideController 控制 SlidablePanel 和操作按钮,不仅限于手势操作。

所有操作按钮可以在 SlidablePanel 打开时展开

SlidablePanel 展开示例

不同的运动模式

  • ActionMotion.drawer Drawer Motion

  • ActionMotion.scroll Scroll Motion

  • ActionMotion.behind Behind Motion

禁用手势滑动

通过设置 gestureDisabled: true 可以避免手势滑动,并继续通过 SlideController 编程控制滑动。

SlidablePanel(
  ...
  gestureDisabled: true,
  ...
)

初始打开位置

通过指定 SlideControllerinitOpenedPosition,可以在不使用 WidgetsBinding.instance.addPostFrameCallback 的情况下,在指定位置打开操作按钮。

final SlideController _slideController = SlideController(
  usePreActionController: true,
  usePostActionController: true,
  initOpenedPosition: ActionPosition.pre,
);

快速开始

首先,确保你已经在 pubspec.yaml 文件中添加了依赖:

dependencies:
  flutter_slidable_panel: ^latest_version

然后,导入并使用该插件:

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

class SizedSlidableExample extends StatefulWidget {
  const SizedSlidableExample({super.key});

  @override
  State<SizedSlidableExample> createState() => _SizedSlidableExampleState();
}

class _SizedSlidableExampleState extends State<SizedSlidableExample> {
  final SlideController _slideController = SlideController(
    usePreActionController: true,
    usePostActionController: true,
  );

  @override
  void dispose() {
    _slideController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Sized Slidable Example'),
      ),
      body: Center(
        child: SlidablePanel(
          controller: _slideController,
          maxSlideThreshold: 0.8,
          axis: Axis.horizontal,
          preActions: [
            TextButton(
              onPressed: () {
                _slideController.toggleAction(0);
              },
              style: TextButton.styleFrom(
                backgroundColor: Colors.greenAccent,
                shape: const RoundedRectangleBorder(),
              ),
              child: const Text("PreAction"),
            ),
            TextButton(
              onPressed: () {
                _slideController.toggleAction(1);
              },
              style: TextButton.styleFrom(
                backgroundColor: Colors.redAccent,
                shape: const RoundedRectangleBorder(),
              ),
              child: const Text("PreAction"),
            ),
          ],
          postActions: [
            TextButton(
              onPressed: () {
                _slideController.toggleAction(0);
              },
              style: TextButton.styleFrom(
                backgroundColor: Colors.greenAccent,
                shape: const RoundedRectangleBorder(),
              ),
              child: const Text("PostAction"),
            ),
            TextButton(
              onPressed: () {
                _slideController.toggleAction(1);
              },
              style: TextButton.styleFrom(
                backgroundColor: Colors.redAccent,
                shape: const RoundedRectangleBorder(),
              ),
              child: const Text("PostAction"),
            ),
          ],
          child: GestureDetector(
            onTap: () {
              _slideController.dismiss();
            },
            child: const DecoratedBox(
              decoration: BoxDecoration(color: Colors.blue),
              child: SizedBox(
                width: 250,
                height: 100,
                child: Center(
                  child: Text(
                    'Slide me',
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

使用方法

创建 SlideController

final SlideController _slideController = SlideController(
  usePreActionController: true,
  usePostActionController: true,
);
  • usePreActionController: 是否启用展开/折叠前置操作按钮。
  • usePostActionController: 是否启用展开/折叠后置操作按钮。

使用不同的运动模式和对齐方式

可以通过 SlidablePanel.preActionLayoutSlidablePanel.postActionLayout 设置不同的动作布局和对齐方式。

ActionLayout(
  alignment: ActionAlignment.spaceEvenly || ActionAlignment.flex,
  motion: ActionMotion.behind || ActionMotion.drawer || ActionMotion.scroll,
)

在开始滑动时执行某些操作

可以设置 onSlideStart 来在开始滑动时执行一些工作,例如当开始滑动时关闭其他 SlidablePanel

SlidablePanel(
  onSlideStart: () {
    // 执行某些操作
  },
)

编程控制 SlideController

打开面板

_slideController.open({
  ActionPosition position = ActionPosition.pre,
  Curve curve = Curves.easeInOut,
  Duration duration = const Duration(milliseconds: 300),
});

关闭面板

_slideController.dismiss({
  Curve curve = Curves.easeInOut,
  Duration duration = const Duration(milliseconds: 300),
});

检查当前打开的位置

ActionPosition openedPosition = _slideController.openedPosition;

展开指定索引的操作按钮

_slideController.expand(
  int index,
  {Curve curve = Curves.easeInOut, Duration duration = const Duration(milliseconds: 150)}
);

折叠指定索引的操作按钮

_slideController.collapse(
  int index,
  {required ActionPosition position, Curve curve = Curves.easeInOut, Duration duration = const Duration(milliseconds: 150)}
);

切换指定索引的操作按钮

_slideController.toggleAction(
  int index,
  {Curve curve = Curves.easeInOut, Duration duration = const Duration(milliseconds: 150)}
);

检测指定索引的操作按钮是否已展开

bool isExpanded = _slideController.hasExpandedAt(int index);

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

1 回复

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


当然,以下是如何在Flutter项目中使用flutter_slidable_panel插件的详细代码示例。这个插件允许你创建一个可以滑动的面板,非常适合创建类似抽屉导航或者侧边栏菜单的效果。

首先,确保你已经在pubspec.yaml文件中添加了flutter_slidable_panel依赖:

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

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

接下来,你可以在你的Flutter项目中使用flutter_slidable_panel。以下是一个简单的例子,展示如何创建一个基本的滑动面板:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Slidable Panel Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 300),
      vsync: this,
    )..addListener(() {
        setState(() {});
      });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Slidable Panel'),
      ),
      body: SlidablePanel(
        panel: Center(
          child: Text(
            'This is the slidable panel content',
            style: TextStyle(fontSize: 24),
          ),
        ),
        content: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Main content'),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  // Toggle the panel state
                  setState(() {
                    _controller.reverse();
                  });
                },
                child: Text('Toggle Panel'),
              ),
            ],
          ),
        ),
        animationController: _controller,
        borderRadius: BorderRadius.circular(20),
        panelWidth: 250,
        minFlingVelocity: 500,
        maxHeight: MediaQuery.of(context).size.height * 0.7,
        onClose: () {
          // This is called when the panel is fully closed
          print('Panel closed');
        },
        onOpen: () {
          // This is called when the panel is fully opened
          print('Panel opened');
        },
      ),
    );
  }
}

代码解释:

  1. 依赖导入:确保在pubspec.yaml中添加了flutter_slidable_panel依赖。
  2. 创建主应用MyApp是一个基本的Flutter应用,包含了一个主题和MyHomePage
  3. 创建主页MyHomePage是一个有状态的小部件,包含了一个动画控制器_controller,用于控制面板的滑动动画。
  4. 初始化动画控制器:在initState方法中初始化动画控制器,并在dispose方法中释放它。
  5. 构建UI
    • 使用SlidablePanel小部件来创建滑动面板。
    • panel参数是滑动面板的内容。
    • content参数是主内容区域。
    • animationController参数控制滑动动画。
    • borderRadiuspanelWidthminFlingVelocitymaxHeight参数用于自定义面板的外观和行为。
    • onCloseonOpen回调用于在面板完全关闭或打开时执行操作。

这个示例展示了如何创建和自定义一个基本的滑动面板。你可以根据需要进一步调整这些参数和添加更多功能。

回到顶部