永久持久化底部表单(Flutter)

13

我希望我的底部面板在我从代码中关闭它之前一直停留在屏幕上。通常情况下,可以通过按返回按钮(设备或应用栏)甚至只需向下滑动手势来关闭底部面板。如何禁用此功能?

_scaffoldKey.currentState
        .showBottomSheet<Null>((BuildContext context) {
      final ThemeData themeData = Theme.of(context);
      return new ControlBottom(
        songName: songName,
        url: url,
        play: play,
        pause: pause,
        state: test,
        themeData: themeData,
      );
    }).closed.whenComplete((){

    });

控制按钮是一个不同的小部件。

5个回答

24

Scaffold现在具有底部表格参数,通过向下滑动屏幕无法关闭此底部表格。

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(....),
        bottomSheet: Container(
            child: Text('Hello World'),
        ),
    );
  }

这对我不起作用,请给我一些例子帮助我。 - Savad
1
当您使用 Scaffold 的 bottomSheet 属性指定底部表单时,圆角将无效(也许有某种方法,但经过 1 小时的搜索后,我回到了之前基于 Stack 实现的底部表单)。 - Bartek Pacia

3

你也可以使用WillPopScope Widget来控制按下返回按钮的操作:

Widget _buildBottomSheet() {
    return WillPopScope(
        onWillPop: () {
            **here you can handle back button pressing. Just leave it empty to disable back button**
        },
        child: **your bottom sheet**
        )),
    );
}

1
谢谢,这实际上防止了后退按钮在模态表单上执行,有没有办法强制后退按钮在打开底部表单之前存在的导航堆栈上工作。 - skjagini
@skjagini,你找到解决方案了吗? - Zubair Rehman

1
你可以通过在 leading 属性中提供一个空的 container 来移除应用栏的返回按钮。
AppBar(
  leading: Container(),
);

但是我们无法控制设备的后退按钮,而且底部表单在按下后退按钮时会消失。
其中一种替代方法可以使用带有定位和透明度小部件的堆栈。
示例:
Stack(
  children: <Widget>[
  // your code here
    Positioned(
      left: 0.0,
      right: 0.0,
      bottom: 0.0,
      child: Opacity(
        opacity: _opacityLevel,
        child: Card(
          child: //Your Code Here,
        ),
      ),
    ),
  // your code here
  ],
);

当选择一首歌曲时,您可以将_opacityLevel从0.0更改为1.0。

根据您的代码,我可以看出您会在顶部有一个listView和底部的音乐控制器。请确保在listView末尾添加一些Padding,以便当您滚动到最底部时,最后一个列表项不会隐藏在音乐控制器卡片后面。

如果您想进一步自定义音乐控制器的外观和感觉,您可以使用animationControllersizeAnimation,像bottomSheet一样从底部滑动它。

希望这可以帮助您。


谢谢,特别是最后一项事情。我真的没有想到。 - Ayush Singh

0

请将以下参数添加到showModalBottomSheet方法中:

isDismissible: false, enableDrag: false,

0
我想要一个可以上下拖动但不关闭的底部弹出窗口。因此,首先我为我的modalBottomSheet创建了一个函数。
Future modalBottomSheetShow(BuildContext context) {
    return showModalBottomSheet(
      backgroundColor: Colors.transparent,
      context: context,
      builder: (context) => buildSheet(),
      isDismissible: false,
      elevation: 0,
    );
  }

接下来,我使用了showModalBottomSheet()的.whenComplete()方法来递归调用modalBottomSheetShow()函数。
  Future modalBottomSheetShow(BuildContext context) {
    return showModalBottomSheet(
      backgroundColor: Colors.transparent,
      context: context,
      builder: (context) => buildSheet(),
      isDismissible: false,
      elevation: 0,
    ).whenComplete(() => modalBottomSheetShow(context));
  }

接下来,每当我想要一个底部工作表时,我只需调用modalBottomSheetShow()。它在递归结束之前无法关闭。以下是完整的参考代码:
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);
  static const idScreen = "HomePage";
  @override
  State<HomePage> createState() => _HomePageState();
}



  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((_) async {
      modalBottomSheetShow(context);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        toolbarHeight: 0,
        elevation: 0,
        backgroundColor: Colors.black,
      ),
    );
  }

  Widget buildSheet() {
    return DraggableScrollableSheet(
      initialChildSize: 0.6,
      builder: (BuildContext context, ScrollController scrollController) {
        return Container(
          decoration: BoxDecoration(color: Colors.white, boxShadow: [
            BoxShadow(
              color: Color(0x6C000000),
              spreadRadius: 5,
              blurRadius: 20,
              offset: Offset(0, 0),
            )
          ]),
          padding: EdgeInsets.all(16),
        );
      },
    );
  }

  Future modalBottomSheetShow(BuildContext context) {
    return showModalBottomSheet(
      backgroundColor: Colors.transparent,
      context: context,
      builder: (context) => buildSheet(),
      isDismissible: false,
      elevation: 0,
    ).whenComplete(() => modalBottomSheetShow(context));
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接