Flutter滑动面板插件sliding_sheet的使用

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

Flutter滑动面板插件sliding_sheet的使用

sliding_sheet 是一个可以在单个手势内拖动和滚动,并且可以吸附到一组指定高度的小组件。下面是 sliding_sheet 的使用方法和示例代码。

安装

首先,在 pubspec.yaml 文件中添加依赖:

dependencies:
  sliding_sheet: ^0.5.2

然后在命令行中安装包:

flutter packages get

如果你喜欢这个包,别忘了给它一个星以支持它的发展:

使用

作为永久(或持久)组件

这种方法可以用来永久显示 SlidingSheet 组件(通常在其他组件之上)。如示例所示:

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.grey.shade200,
    appBar: AppBar(
      title: Text('Simple Example'),
    ),
    body: SlidingSheet(
      elevation: 8,
      cornerRadius: 16,
      snapSpec: const SnapSpec(
        // 启用吸附功能。默认为true。
        snap: true,
        // 设置自定义吸附点。
        snappings: [0.4, 0.7, 1.0],
        // 指定吸附点相对于什么。在这种情况下,吸附点相对于可扩展的高度。
        positioning: SnapPositioning.relativeToAvailableSpace,
      ),
      // 背景组件将显示在 SlidingSheet 下方,
      // 并且可以应用视差效果。
      body: Center(
        child: Text('This widget is below the SlidingSheet'),
      ),
      builder: (context, state) {
        // 这是吸附面板的内容,如果内容比吸附面板的高度大,则可以滚动。
        return Container(
          height: 500,
          child: Center(
            child: Text('This is the content of the sheet'),
          ),
        );
      },
    ),
  );
}

结果:

作为 BottomSheetDialog

这种方法可以通过调用 showSlidingBottomSheet 函数并返回一个 SlidingSheetDialog 实例来显示 SlidingSheet

void showAsBottomSheet() async {
  final result = await showSlidingBottomSheet(
    context,
    builder: (context) {
      return SlidingSheetDialog(
        elevation: 8,
        cornerRadius: 16,
        snapSpec: const SnapSpec(
          snap: true,
          snappings: [0.4, 0.7, 1.0],
          positioning: SnapPositioning.relativeToAvailableSpace,
        ),
        builder: (context, state) {
          return Container(
            height: 400,
            child: Center(
              child: Material(
                child: InkWell(
                  onTap: () => Navigator.pop(context, 'This is the result.'),
                  child: Padding(
                    padding: const EdgeInsets.all(16),
                    child: Text(
                      'This is the content of the sheet',
                      style: Theme.of(context).textTheme.body1,
                    ),
                  ),
                ),
              ),
            ),
          );
        },
      );
    }
  );

  print(result); // This is the result.
}

结果:

吸附功能

SlidingSheet 可以吸附到多个高度或不吸附任何高度。通过传递 SnapSpec 实例可以自定义吸附行为。

SnapSpec(
  snap: true, // 如果为真,SlidingSheet 将吸附到提供的 snappings。
  snappings: [0.4, 0.7, 1.0], // 吸附点。
  positioning: SnapPositioning.relativeToAvailableSpace, // 吸附点的位置。
  onSnap: (state, snap) { // 当 SlidingSheet 吸附到某个高度时调用。
    print('Snapped to $snap');
  },
)

还可以利用预构建的吸附点来吸附到头部或尾部等特定位置。

SheetController

SheetController 可以手动改变 SlidingSheet 的状态。只需将 SheetController 实例传递给 SlidingSheet 即可。也可以使用静态方法 SheetController.of(context) 获取最近的 SlidingSheetSheetController

class SheetController {
  void expand(); // 扩展 SlidingSheet 到最大高度。
  void collapse(); // 收缩 SlidingSheet 到最小高度。
  void snapToExtent(double extent); // 吸附到任意高度。
  void scrollTo(double offset); // 滚动到给定偏移量。
  void rebuild(); // 重新构建 SlidingSheet 的所有子组件。
  void show(); // 显示 SlidingSheet。
  void hide(); // 隐藏 SlidingSheet。
}

头部和尾部

头部和尾部是 SlidingSheet 中不会滚动的 UI 元素。头部位于顶部,尾部位于底部。中间的内容部分会滚动。

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.grey.shade200,
    appBar: AppBar(
      title: Text('Simple Example'),
    ),
    body: Stack(
      children: <Widget>[
        SlidingSheet(
          elevation: 8,
          cornerRadius: 16,
          snapSpec: const SnapSpec(
            snap: true,
            snappings: [112, 400, double.infinity],
            positioning: SnapPositioning.pixelOffset,
          ),
          builder: (context, state) {
            return Container(
              height: 500,
              child: Center(
                child: Text(
                  'This is the content of the sheet',
                  style: Theme.of(context).textTheme.body1,
                ),
              ),
            );
          },
          headerBuilder: (context, state) {
            return Container(
              height: 56,
              width: double.infinity,
              color: Colors.green,
              alignment: Alignment.center,
              child: Text(
                'This is the header',
                style: Theme.of(context).textTheme.body1.copyWith(color: Colors.white),
              ),
            );
          },
          footerBuilder: (context, state) {
            return Container(
              height: 56,
              width: double.infinity,
              color: Colors.yellow,
              alignment: Alignment.center,
              child: Text(
                'This is the footer',
                style: Theme.of(context).textTheme.body1.copyWith(color: Colors.black),
              ),
            );
          },
        ),
      ],
    ),
  );
}

结果:

ListViews 和 Columns

SlidingSheet 的子组件不允许无限(无边界)高度。因此,当使用 ListView 时,请确保设置 shrinkWraptrue 并且 physicsNeverScrollableScrollPhysics。同样地,当使用 Column 作为 SlidingSheet 的子组件时,请确保设置 mainAxisSizeMainAxisSize.min

Material 效应

为了改变交互时的界面,可以在 SlidingSheet 中传递一个回调到 listener 字段,该回调会在滑动或滚动时被调用。你可以根据当前的 SheetState 来重建你的界面。使用 SheetController.rebuild() 可以在使用 bottomSheetDialog 时重新构建面板。

return SheetListenerBuilder(
  buildWhen: (oldState, newState) => oldState.isAtTop != newState.isAtTop,
  builder: (context, state) {
    return AnimatedContainer(
      elevation: !state.isAtTop ? elevation : 0.0,
      duration: const Duration(milliseconds: 400),
      child: child,
    );
  },
);

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

1 回复

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


当然,以下是如何在Flutter项目中使用sliding_sheet插件来实现滑动面板功能的示例代码。sliding_sheet是一个流行的Flutter插件,它允许你创建类似于底部面板(Bottom Sheet)的滑动组件,但提供了更多的自定义选项和动画效果。

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

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

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

接下来,我们来看一个完整的示例代码,展示如何使用sliding_sheet

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

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

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

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

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

  @override
  void initState() {
    super.initState();
    _controller = SlidingSheetController();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Sliding Sheet Demo'),
      ),
      body: Column(
        children: [
          Expanded(
            child: Center(
              child: ElevatedButton(
                onPressed: () {
                  // 打开滑动面板
                  _controller.expand();
                },
                child: Text('Open Sheet'),
              ),
            ),
          ),
          SlidingSheet(
            controller: _controller,
            sheet: Container(
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
              ),
              padding: EdgeInsets.all(16),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Text('这是一个滑动面板'),
                  SizedBox(height: 16),
                  ElevatedButton(
                    onPressed: () {
                      // 关闭滑动面板
                      _controller.collapse();
                    },
                    child: Text('关闭'),
                  ),
                ],
              ),
            ),
            snapPoints: [100, 300], // 自定义的两个停靠点
            peekHeight: 100, // 初始显示高度
            initialExpansion: 0.5, // 初始展开比例
          ),
        ],
      ),
    );
  }
}

代码解释

  1. 依赖添加:确保在pubspec.yaml中添加了sliding_sheet依赖。

  2. 控制器初始化:在_MyHomePageState中初始化了一个SlidingSheetController,用于控制滑动面板的展开和收起。

  3. 按钮触发:在body中,有一个按钮用于触发滑动面板的展开。点击按钮时,调用_controller.expand()方法。

  4. 滑动面板SlidingSheet组件是滑动面板的主体,设置了controllersheetsnapPointspeekHeightinitialExpansion等属性。

    • controller:用于控制滑动面板的控制器。
    • sheet:滑动面板的内容,这里是一个简单的Container,包含一些文本和一个关闭按钮。
    • snapPoints:定义滑动面板可以停靠的高度列表。
    • peekHeight:滑动面板初始显示的高度。
    • initialExpansion:滑动面板初始的展开比例(0.0到1.0之间)。
  5. 关闭按钮:在滑动面板内部,有一个按钮用于关闭面板,点击时调用_controller.collapse()方法。

这个示例展示了如何使用sliding_sheet插件创建一个简单的滑动面板,并包含了基本的展开和收起功能。你可以根据实际需求进一步自定义和扩展。

回到顶部