Flutter可拖拽底部弹窗插件draggable_bottom_sheet_nullsafety的使用

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

Flutter可拖拽底部弹窗插件draggable_bottom_sheet_nullsafety的使用

这是一个部分可见在屏幕上的底部弹出窗口,可以通过拖动来扩展到全屏。

这个包是draggable_bottom_sheet的适配版本,并增加了空安全支持。

开始使用

  1. pubspec.yaml 文件中添加依赖:
draggable_bottom_sheet_nullsafety: ^1.0.1
  1. 导入包:
import 'package:draggable_bottom_sheet_nullsafety/draggable_bottom_sheet_nullsafety.dart';

参数说明

以下是 DraggableBottomSheet 的参数描述:

参数 类型 描述
backgroundWidget Widget 当展开时会隐藏在底部弹出窗口后面的部件
previewChild Widget 底部弹出窗口未展开时显示的子部件
expandedChild Widget 底部弹出窗口展开时的子部件
alignment Alignment 底部弹出窗口的对齐方式
blurBackground bool 是否在底部弹出窗口扩展时模糊背景(true:模态窗口,false:持久窗口)
expansionExtent double 从最小高度到改变预览子部件为展开子部件的范围
maxEntent double 底部弹出窗口扩展的最大范围
minEntent double 底部弹出窗口的最小范围,也是原始高度
scrollDirection Axis 底部弹出窗口的滚动方向

示例代码

下面是一个完整的示例代码,展示了如何使用 draggable_bottom_sheet_nullsafety 包:

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

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const DraggableBottomSheetExample(
        title: 'Draggable Bottom Sheet Example',
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}

class DraggableBottomSheetExample extends StatelessWidget {
  final String title;

  const DraggableBottomSheetExample({
    Key? key,
    required this.title,
  }) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    const List<IconData> icons = <IconData>[
      Icons.ac_unit,
      Icons.account_balance,
      Icons.adb,
      Icons.add_photo_alternate,
      Icons.format_line_spacing
    ];

    return Scaffold(
      body: DraggableBottomSheet(
        backgroundWidget: Scaffold(
          backgroundColor: Colors.white,
          appBar: AppBar(
            title: Text(title),
            backgroundColor: Colors.deepOrange,
          ),
          body: SizedBox(
            height: 400,
            child: ListView.separated(
              scrollDirection: Axis.horizontal,
              padding: const EdgeInsets.symmetric(vertical: 32),
              itemCount: icons.length,
              itemBuilder: (BuildContext context, int index) => Container(
                width: MediaQuery.of(context).size.width * 0.7,
                height: 200,
                decoration: BoxDecoration(
                  color: Colors.grey,
                  borderRadius: BorderRadius.circular(20),
                ),
                child: Icon(
                  icons[index],
                  color: Colors.white,
                  size: 60,
                ),
              ),
              separatorBuilder: (BuildContext context, int index) =>
                  const SizedBox(width: 10),
            ),
          ),
        ),
        previewChild: Container(
          padding: const EdgeInsets.all(16),
          decoration: const BoxDecoration(
            color: Colors.pink,
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(20),
              topRight: Radius.circular(20),
            ),
          ),
          child: Column(
            children: <Widget>[
              Container(
                width: 40,
                height: 6,
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(10),
                ),
              ),
              const SizedBox(height: 8),
              const Text(
                'Drag Me',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 16,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 16),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: icons.map((icon) {
                  return Container(
                    width: 50,
                    height: 50,
                    margin: const EdgeInsets.only(right: 16),
                    child: Icon(
                      icon,
                      color: Colors.pink,
                      size: 40,
                    ),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(10),
                    ),
                  );
                }).toList(),
              )
            ],
          ),
        ),
        expandedChild: Container(
          padding: const EdgeInsets.all(16),
          decoration: const BoxDecoration(
            color: Colors.pink,
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(20),
              topRight: Radius.circular(20),
            ),
          ),
          child: Column(
            children: <Widget>[
              const Icon(
                Icons.keyboard_arrow_down,
                size: 30,
                color: Colors.white,
              ),
              const SizedBox(height: 8),
              const Text(
                'Hey...I\'m expanding!!!',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 16,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 16),
              Expanded(
                child: GridView.builder(
                  itemCount: icons.length,
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 2,
                    crossAxisSpacing: 10,
                    mainAxisSpacing: 10,
                  ),
                  itemBuilder: (BuildContext context, int index) {
                    return Container(
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(10),
                      ),
                      child: Icon(
                        icons[index],
                        color: Colors.pink,
                        size: 40,
                      ),
                    );
                  },
                ),
              )
            ],
          ),
        ),
        minExtent: 150,
        maxExtent: MediaQuery.of(context).size.height * 0.8,
      ),
    );
  }
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用draggable_bottom_sheet_nullsafety插件的示例代码。这个插件允许你创建一个可拖拽的底部弹窗。

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

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

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

以下是一个完整的示例代码,展示如何使用draggable_bottom_sheet_nullsafety插件:

import 'package:flutter/material.dart';
import 'package:draggable_bottom_sheet_nullsafety/draggable_bottom_sheet.dart';

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  DraggableBottomSheetController? _controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Draggable Bottom Sheet Demo'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            _showDraggableBottomSheet(context);
          },
          child: Text('Show Bottom Sheet'),
        ),
      ),
    );
  }

  void _showDraggableBottomSheet(BuildContext context) {
    _controller = DraggableBottomSheetController();
    showDraggableBottomSheet(
      context: context,
      controller: _controller!,
      builder: (context, scrollController) {
        return Container(
          color: Colors.white,
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Text(
                  'This is a draggable bottom sheet',
                  style: TextStyle(fontSize: 20),
                ),
                SizedBox(height: 20),
                ElevatedButton(
                  onPressed: () {
                    _controller!.close();
                  },
                  child: Text('Close'),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

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

代码解释:

  1. 依赖添加:在pubspec.yaml中添加draggable_bottom_sheet_nullsafety依赖。
  2. 创建应用:在MyApp中定义了一个简单的Flutter应用。
  3. 主页面MyHomePage是一个有状态组件,包含一个按钮,点击按钮时会显示可拖拽的底部弹窗。
  4. 显示底部弹窗_showDraggableBottomSheet方法使用showDraggableBottomSheet函数显示底部弹窗,并初始化一个DraggableBottomSheetController来控制弹窗。
  5. 弹窗内容:在builder回调中定义了弹窗的内容,这里是一个简单的容器,包含一个文本和一个关闭按钮。
  6. 资源释放:在dispose方法中释放_controller资源,避免内存泄漏。

这个示例展示了如何使用draggable_bottom_sheet_nullsafety插件来创建一个可拖拽的底部弹窗,并提供了关闭弹窗的功能。你可以根据需要进一步自定义弹窗的内容和样式。

回到顶部