Flutter模态底部弹出插件wolt_modal_sheet的使用

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

Flutter模态底部弹出插件wolt_modal_sheet的使用

简介

WoltModalSheet 是一个旨在革新Flutter应用中模态页使用的插件。它提供了多页面布局、可滚动内容、响应式设计和自定义模态类型等功能,支持Material和Cupertino风格,并且可以与多种状态管理库集成。

安装

在你的pubspec.yaml文件中添加依赖:

dependencies:
  wolt_modal_sheet: ^最新版本号

然后运行命令安装:

flutter pub get

基本用法

创建一个简单的底部弹出模态框

下面是一个简单的例子,展示了如何创建一个包含列表项的底部弹出模态框。

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

void main() {
  runApp(const WoltModalSheetApp());
}

class WoltModalSheetApp extends StatelessWidget {
  const WoltModalSheetApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: WoltModalSheetHomePage(),
    );
  }
}

class WoltModalSheetHomePage extends StatelessWidget {
  const WoltModalSheetHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Wolt Modal Bottom Sheet Sample'),
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () {
          WoltModalSheet.show(
            context: context,
            pageListBuilder: (bottomSheetContext) => [
              SliverWoltModalSheetPage(
                mainContentSliversBuilder: (context) => [
                  SliverList.builder(
                    itemBuilder: (context, index) {
                      return ListTile(
                        title: Text('Index is $index'),
                        onTap: Navigator.of(bottomSheetContext).pop,
                      );
                    },
                  ),
                ],
              )
            ],
          );
        },
        label: const Text('Trigger Wolt Sheet'),
      ),
    );
  }
}

创建一个多页面底部弹出模态框

这个例子展示了如何创建一个多页面底部弹出模态框,并根据屏幕大小调整其显示方式(例如,在大屏幕上以对话框形式展示)。

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

const double _pagePadding = 16.0;
const double _buttonHeight = 56.0;
const double _bottomPaddingForButton = 150.0;

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

  @override
  State<MultiPageModalSheetExample> createState() =>
      _MultiPageModalSheetExampleState();
}

class _MultiPageModalSheetExampleState
    extends State<MultiPageModalSheetExample> {
  bool _isLightTheme = true;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      themeMode: _isLightTheme ? ThemeMode.light : ThemeMode.dark,
      theme: ThemeData.light().copyWith(
        extensions: const <ThemeExtension>[
          WoltModalSheetThemeData(
            heroImageHeight: 250.0,
            topBarShadowColor: Color(0xFFE4E4E4),
            modalBarrierColor: Colors.black54,
            mainContentScrollPhysics: ClampingScrollPhysics(),
          ),
        ],
      ),
      darkTheme: ThemeData.dark().copyWith(
        extensions: const <ThemeExtension>[
          WoltModalSheetThemeData(
            topBarShadowColor: Color(0xFF121212),
            modalBarrierColor: Colors.white12,
            sabGradientColor: Color(0xFF313236),
            mainContentScrollPhysics: ClampingScrollPhysics(),
          ),
        ],
      ),
      home: Scaffold(
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              WoltModalSheet.show<void>(
                context: context,
                pageListBuilder: (modalSheetContext) {
                  final textTheme = Theme.of(context).textTheme;
                  return [
                    page1(modalSheetContext, textTheme),
                    page2(modalSheetContext, textTheme),
                  ];
                },
                modalTypeBuilder: (context) {
                  final size = MediaQuery.sizeOf(context).width;
                  if (size < 768) {
                    return WoltModalType.bottomSheet();
                  } else {
                    return WoltModalType.dialog();
                  }
                },
                onModalDismissedWithBarrierTap: () {
                  debugPrint('Closed modal sheet with barrier tap');
                  Navigator.of(context).pop();
                },
              );
            },
            child: const SizedBox(
              height: _buttonHeight,
              width: 200.0,
              child: Center(child: Text('Show Modal Sheet')),
            ),
          ),
        ),
      ),
    );
  }

  SliverWoltModalSheetPage page1(
      BuildContext modalSheetContext, TextTheme textTheme) {
    return WoltModalSheetPage(
      hasSabGradient: false,
      stickyActionBar: Padding(
        padding: const EdgeInsets.all(_pagePadding),
        child: Column(
          children: [
            ElevatedButton(
              onPressed: Navigator.of(modalSheetContext).pop,
              child: const SizedBox(
                height: _buttonHeight,
                width: double.infinity,
                child: Center(child: Text('Cancel')),
              ),
            ),
            const SizedBox(height: 8),
            ElevatedButton(
              onPressed: WoltModalSheet.of(modalSheetContext).showNext,
              child: const SizedBox(
                height: _buttonHeight,
                width: double.infinity,
                child: Center(child: Text('Next page')),
              ),
            ),
          ],
        ),
      ),
      topBarTitle: Text('Pagination', style: textTheme.titleSmall),
      isTopBarLayerAlwaysVisible: true,
      trailingNavBarWidget: IconButton(
        padding: const EdgeInsets.all(_pagePadding),
        icon: const Icon(Icons.close),
        onPressed: Navigator.of(modalSheetContext).pop,
      ),
      child: const Padding(
          padding: EdgeInsets.fromLTRB(
            _pagePadding,
            _pagePadding,
            _pagePadding,
            _bottomPaddingForButton,
          ),
          child: Text(
            '''
Pagination involves a sequence of screens the user navigates sequentially. We chose a lateral motion for these transitions. When proceeding forward, the next screen emerges from the right; moving backward, the screen reverts to its original position. We felt that sliding the next screen entirely from the right could be overly distracting. As a result, we decided to move and fade in the next page using 30% of the modal side.
''',
          )),
    );
  }

  SliverWoltModalSheetPage page2(
      BuildContext modalSheetContext, TextTheme textTheme) {
    return SliverWoltModalSheetPage(
      pageTitle: Padding(
        padding: const EdgeInsets.all(_pagePadding),
        child: Text(
          'Material Colors',
          style: textTheme.headlineMedium!.copyWith(fontWeight: FontWeight.bold),
        ),
      ),
      leadingNavBarWidget: IconButton(
        padding: const EdgeInsets.all(_pagePadding),
        icon: const Icon(Icons.arrow_back_rounded),
        onPressed: WoltModalSheet.of(modalSheetContext).showPrevious,
      ),
      trailingNavBarWidget: IconButton(
        padding: const EdgeInsets.all(_pagePadding),
        icon: const Icon(Icons.close),
        onPressed: Navigator.of(modalSheetContext).pop,
      ),
      mainContentSliversBuilder: (context) => [
        SliverGrid(
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            mainAxisSpacing: 10.0,
            crossAxisSpacing: 10.0,
            childAspectRatio: 2.0,
          ),
          delegate: SliverChildBuilderDelegate(
            (_, index) => ColorTile(color: Colors.primaries[index % Colors.primaries.length]),
            childCount: 20,
          ),
        ),
        SliverList(
          delegate: SliverChildBuilderDelegate(
            (_, index) => ColorTile(color: Colors.accents[index % Colors.accents.length]),
            childCount: 5,
          ),
        ),
      ],
    );
  }
}

class ColorTile extends StatelessWidget {
  final Color color;

  const ColorTile({super.key, required this.color});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: color,
      height: 100,
      child: Center(
        child: Text(
          color.toString(),
          style: TextStyle(
            color: color.computeLuminance() > 0.5 ? Colors.black : Colors.white,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
    );
  }
}

以上代码演示了如何创建一个具有多个页面的底部弹出模态框,并展示了如何根据屏幕尺寸调整其显示模式。通过这种方式,你可以为用户提供更加灵活和响应式的用户体验。


更多关于Flutter模态底部弹出插件wolt_modal_sheet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter模态底部弹出插件wolt_modal_sheet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用wolt_modal_sheet插件来创建模态底部弹出的示例代码。这个插件允许你以类似于Apple Maps和Wolt应用中的方式显示模态底部弹出窗口。

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

dependencies:
  flutter:
    sdk: flutter
  wolt_modal_sheet: ^latest_version  # 请确保使用最新版本号

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

接下来是一个简单的示例,展示了如何使用wolt_modal_sheet来显示一个模态底部弹出窗口:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {

  void showModalBottomSheet() {
    showModalBottomSheet<void>(
      context: context,
      isScrollControlled: true,
      builder: (BuildContext context) {
        return WoltModalSheet(
          title: Text('模态底部弹出'),
          content: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Text('这是一个模态底部弹出窗口的示例。'),
                SizedBox(height: 16.0),
                ElevatedButton(
                  onPressed: () => Navigator.pop(context),
                  child: Text('关闭'),
                ),
              ],
            ),
          ),
          actions: <Widget>[
            ElevatedButton(
              onPressed: () {
                // 执行某些操作,比如保存数据
                Navigator.pop(context);
              },
              child: Text('保存'),
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Wolt Modal Sheet 示例'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: showModalBottomSheet,
          child: Text('显示模态底部弹出'),
        ),
      ),
    );
  }
}

解释

  1. 依赖添加

    • pubspec.yaml中添加wolt_modal_sheet依赖。
  2. 导入包

    • 在你的Dart文件中导入wolt_modal_sheet包。
  3. 创建模态底部弹出

    • 使用showModalBottomSheet函数来显示模态底部弹出。
    • 使用WoltModalSheet小部件来自定义弹出的外观和内容。
    • title参数用于设置标题。
    • content参数用于设置主要内容。
    • actions参数用于设置底部操作按钮。
  4. 按钮触发

    • HomeScreen中创建一个按钮,点击按钮时调用showModalBottomSheet函数来显示模态底部弹出。

这个示例展示了如何使用wolt_modal_sheet来创建一个具有标题、内容和操作按钮的模态底部弹出窗口。你可以根据需要进一步自定义和扩展这个示例。

回到顶部