Flutter滑动面板插件flutter_sliding_panel的使用

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

Flutter滑动面板插件flutter_sliding_panel的使用

flutter_sliding_panel 是一个功能强大且易于使用的Flutter插件,它允许开发者轻松创建具有平滑滑动和智能锚定行为的可滑动面板。本文将介绍如何在Flutter项目中使用该插件,并提供完整的示例代码。

添加依赖

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

dependencies:
  flutter_sliding_panel: ^latest_version

然后运行以下命令来安装依赖:

dart pub add flutter_sliding_panel

导入包

在需要使用 flutter_sliding_panel 的文件中导入该包:

import 'package:flutter_sliding_panel/flutter_sliding_panel.dart';

示例Demo

基本示例:非滚动内容的滑动面板

这是一个最基本的滑动面板示例,展示了如何创建一个简单的滑动面板:

SlidingPanel(
  controller: SlidingPanelController(),
  config: SlidingPanelConfig(
    anchorPosition: MediaQuery.of(context).size.height / 2,
    expandPosition: MediaQuery.of(context).size.height - 200,
  ),
  panelContent: Text(
    '\nDRAG ME!',
    textAlign: TextAlign.center,
    style: TextStyle(
      fontSize: 40,
      letterSpacing: -1,
      fontWeight: FontWeight.bold,
      fontStyle: FontStyle.italic,
      color: Theme.of(context).colorScheme.onSurface,
    ),
  ),
);

滚动内容的滑动面板

当面板内容为可滚动的内容时,可以使用 SlidingPanel.scrollableContent() 方法:

SlidingPanel.scrollableContent(
  controller: SlidingPanelController(),
  config: SlidingPanelConfig(
    anchorPosition: MediaQuery.of(context).size.height / 2,
    expandPosition: MediaQuery.of(context).size.height - 200,
  ),
  panelContentBuilder: (controller, physics) => ListView.builder(
    controller: controller,
    physics: physics,
    itemBuilder: (context, index) => Container(
      height: 50,
      alignment: Alignment.center,
      child: Text('$index'),
    ),
  ),
);

多个滚动内容的滑动面板

如果需要在面板中包含多个滚动视图,可以使用 SlidingPanel.multiScrollableContent() 方法:

SlidingPanel.multiScrollableContent(
  controller: SlidingPanelController(),
  scrollableChildCount: 2,
  config: SlidingPanelConfig(
    anchorPosition: MediaQuery.of(context).size.height / 2,
    expandPosition: MediaQuery.of(context).size.height - 200,
  ),
  panelContentBuilder: (controller, physics) => TabBarView(
    controller: tabController,
    children: List.generate(
      2,
      (index) => MultiScrollableChildTab(
        controller: controller[index],
        physics: physics[index],
        tabIndex: index,
      ),
    ),
  ),
);

显示刷新指示器

为了在面板过度滚动时显示刷新指示器,可以传递 SlidingPanelRefresherConfigdragToRefreshConfig 参数:

SlidingPanel(
  controller: SlidingPanelController(),
  config: SlidingPanelConfig(
    anchorPosition: MediaQuery.of(context).size.height / 2,
    expandPosition: MediaQuery.of(context).size.height - 200,
  ),
  dragToRefreshConfig: SlidingPanelRefresherConfig(
    onRefresh: () async {
      // 实现刷新逻辑
      await Future.delayed(const Duration(milliseconds: 1500), () {});
    },
  ),
  panelContent: Text(
    '\nDRAG ME!',
    textAlign: TextAlign.center,
    style: TextStyle(
      fontSize: 40,
      letterSpacing: -1,
      fontWeight: FontWeight.bold,
      fontStyle: FontStyle.italic,
      color: Theme.of(context).colorScheme.onSurface,
    ),
  ),
);

完整示例代码

下面是一个完整的示例代码,包含了基本的滑动面板、带有滚动内容的滑动面板以及带有多个滚动内容的滑动面板:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Sliding Panel Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

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

class _MyHomePageState extends State<MyHomePage> {
  final controller = SlidingPanelController();
  int slidingPanelTypeChoice = 0;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter Sliding Panel')),
      floatingActionButton: FloatingActionButton(
        child: ValueListenableBuilder<SlidingPanelDetail>(
          valueListenable: controller,
          builder: (_, detail, __) {
            return Icon(
              detail.status == SlidingPanelStatus.anchored
                  ? Icons.keyboard_arrow_up_rounded
                  : Icons.keyboard_arrow_down_rounded,
            );
          },
        ),
        onPressed: () {
          if (controller.status == SlidingPanelStatus.anchored) {
            controller.expand();
          } else {
            controller.anchor();
          }
        },
      ),
      body: _slidingPanelWidget(
        ListView.builder(
          itemCount: 3,
          padding: const EdgeInsets.all(20),
          itemBuilder: (context, index) => Padding(
            padding: const EdgeInsets.only(bottom: 8),
            child: ElevatedButton(
              onPressed: () => setState(() => slidingPanelTypeChoice = index),
              child: Text(_getTypeFromIndex(index)),
            ),
          ),
        ),
      ),
    );
  }

  String _getTypeFromIndex(int index) {
    switch (index) {
      case 0:
        return 'Non-Scrollable';
      case 1:
        return 'Scrollable';
      case 2:
        return 'Multi Scrollable';
      default:
        return '';
    }
  }

  Widget _slidingPanelWidget(Widget body) {
    switch (slidingPanelTypeChoice) {
      case 0:
        return SlidingPanelExample(controller: controller, body: body);
      case 1:
        return ScrollableContentSlidingPanelExample(controller: controller, body: body);
      case 2:
        return MultiScrollableContentSlidingPanelExample(controller: controller, body: body);
      default:
        return const SizedBox();
    }
  }
}

// 其他类定义(如SlidingPanelExample, ScrollableContentSlidingPanelExample等)请参考上面的示例代码。

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

1 回复

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


当然,下面是一个关于如何使用Flutter滑动面板插件flutter_sliding_panel的示例代码。这个插件允许你创建一个可以上下滑动的面板,非常适合在需要展示额外信息或菜单时使用。

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

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

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

接下来是一个简单的使用示例:

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

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

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

class SlidingPanelScreen extends StatefulWidget {
  @override
  _SlidingPanelScreenState createState() => _SlidingPanelScreenState();
}

class _SlidingPanelScreenState extends State<SlidingPanelScreen> 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 Sliding Panel'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Main Content', style: TextStyle(fontSize: 24)),
            SizedBox(height: 20),
            SlidingPanel(
              controller: _controller,
              panel: Container(
                color: Colors.grey[200],
                padding: EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('Panel Content', style: TextStyle(fontSize: 20)),
                    Text('This is some extra information or a menu.', style: TextStyle(fontSize: 16)),
                  ],
                ),
              ),
              collapse: false,
              height: 200,
              onPanelSlide: (double position) {
                // You can handle the panel slide position here if needed
                print('Panel position: $position');
              },
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  if (_controller.isCompleted) {
                    _controller.reverse();
                  } else {
                    _controller.forward();
                  }
                });
              },
              child: Text('Toggle Panel'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中:

  1. 我们创建了一个SlidingPanelScreen,它是一个StatefulWidget,因为我们需要控制面板的动画状态。
  2. _SlidingPanelScreenState中,我们初始化了一个AnimationController来控制面板的展开和收起。
  3. SlidingPanel组件被添加到主内容下面。你可以设置它的高度(height),是否允许完全折叠(collapse),以及一个回调函数onPanelSlide来处理面板滑动时的位置变化。
  4. 一个ElevatedButton被添加到页面上,点击它可以切换面板的展开和收起状态。

这个示例展示了如何使用flutter_sliding_panel插件创建一个基本的滑动面板。你可以根据需要进一步自定义和扩展这个示例。

回到顶部