Flutter:滑动面板

前言

无意中发现了这个库,发现现在很多app中都有类似的功能。以手机b站为例,当你在看视频时,点击评论,视频会向上偏移,下方划出评论界面。

sliding_up_panel

SlidingUpPanel是一个Flutter插件,用于创建滑动面板效果。它可以使内容面板在屏幕底部向上滑动,显示隐藏的内容面板,并且还可以根据需要进行手势控制。

SlidingUpPanel提供了许多自定义选项,可以根据具体需求来调整面板的外观和行为。例如,您可以设置面板的高度、背景颜色、边框等。您还可以定义面板打开和关闭的动画效果,以及触发打开和关闭面板的手势。

官方文档
https://pub-web.flutter-io.cn/packages/sliding_up_panel

安装

flutter pub add sliding_up_panel

下面只介绍基本用法,关于其他用法可以自行查看官方文档

示例1

推荐作为根节点使用


  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('滑动面板'),
        ),
        body: SlidingUpPanel(
          // 定义了面板展开时显示的内容
          panel: const Center(
            child: Text('这是滑动面板'),
          ),
          // 定义面子这段时显示的小部件
          collapsed: Container(
            decoration: BoxDecoration(
              color: Colors.blueGrey,
              borderRadius: BorderRadius.circular(10),
            ),
            child: const Center(
              child: Text('点击展开滑动面板'),
            ),
          ),
          // 定义了面板闭合时显示的内容
          body: const Center(
            child: Text('这是主要内容区域'),
          ),
        ),
    );
  }

在这里插入图片描述
示例2
嵌套SlidingUpPanel不建议使用此方法,但仍可以使用此方法。这种方式可以使得panel的内容和body的内容都可以同时显示出来

class SwitcherContainerState extends State<SwitcherContainer> {
  // 创建一个面板控制器
  final PanelController _panelController = PanelController();
  // 面板是否打开
  bool _isPanelOpen = false;
  // 面板类型:works(up主其他作品)、comment(评论)
  String _panelType = 'works';

  double _heightFactor = 2;

  // 切换面板状态
  void _togglePanel() {
    double height = 0;
    if (_isPanelOpen) {
      height = 2;
      _panelController.close();
    } else {
      height = 0.8;
      _panelController.open();
    }
    setState(() {
      _isPanelOpen = !_isPanelOpen;
      _heightFactor = height;
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('滑动面板'),
      ),
      body: Stack(
        children: [
          Center(
            heightFactor: _heightFactor,
            child: Stack(
              children: [
                Container(
                  width: 300,
                  height: 300,
                  color: Colors.red,
                  child: const Center(
                    child: Text("这是视频区域"),
                  ),
                ),
                Positioned(
                    right: 20,
                    child: TextButton(
                      onPressed: () {
                        setState(() {
                          _panelType = 'comment';
                        });
                        _togglePanel();
                      },
                      child: const Text(
                        "评论",
                        style: TextStyle(color: Colors.white),
                      ),
                    ))
              ],
            ),
          ),
          SlidingUpPanel(
            controller: _panelController,
            //禁用滑动展开
            isDraggable: false,
            // 面板最大展开高度
            maxHeight: 400,
            // 定义了面板展开时显示的内容,这里添加可滚动元素
            panelBuilder: (ScrollController sc) {
              return Container(
                // 这里要在listView外套一层Container,并设置向下的padding,否则第一条数据会被header展示的内容遮挡
                padding: const EdgeInsets.only(top: 40),
                child: ListView.builder(
                    controller: sc,
                    itemCount: 6,
                    itemBuilder: (BuildContext context, int i) {
                      return Container(
                        width: MediaQuery.of(context).size.width,
                        height: 80,
                        padding: const EdgeInsets.all(5),
                        decoration: BoxDecoration(
                            border: Border.all(color: Colors.grey, width: 1)),
                        child: Text(_panelType == 'works'
                            ? "作品${i + 1}"
                            : "评论${i + 1}"),
                      );
                    }),
              );
            },
            // 浮动在 上方并附加到 顶部的可选持久小部件
            header: Container(
              width: MediaQuery.of(context).size.width,
              height: 40,
              color: Colors.red,
              child: const Text(
                "up主的其他内容",
                style: TextStyle(color: Colors.white),
              ),
            ),
            // 定义面子这段时显示的小部件
            collapsed: GestureDetector(
              onTap: () {
                setState(() {
                  _panelType = 'works';
                });
                _togglePanel();
              },
              child: Container(
                color: Colors.blueGrey,
                child: const Center(
                  child: Text('这个视频的一些介绍'),
                ),
              ),
            ),
            // 定义了面板闭合时显示的内容
            body: const SizedBox.shrink(),
          )
        ],
      ),
    );
  }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无知的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值