禁用拖动关闭showModalBottomSheet功能

19

我该如何禁用/取消底部弹窗模态框的下拉手势,以便用户可以在模态框内进行交互而不会意外关闭模态框?

下面更新了实际的底部弹窗模态框。

return showModalBottomSheet(
    context: context,
    builder: (BuildContext context) {
        ...
    }
}
4个回答

25

1
谢谢,我不知道实际上有一个BottomSheet。不幸的是,没有BottomSheet使用案例的示例,“BottomSheet小部件本身很少直接使用。”你能否创建一个类似于Modal“showModalBottomSheet”版本的示例? - Jesse
尝试像这个一样的东西。鸣谢:这里 - Willy
哦,这两个链接都没有使用 BottomSheet - Jesse
通过进一步搜索"enableDrag"关键词,我实际上找不到任何使用该属性的例子。 - Jesse
似乎enableDrag属性在主通道中可用,但在稳定版中尚不可用。 - fvisticot
超棒的解决方案 - Fathah Cr

14

您可以尝试使用带有 onVerticalDragStart = (_) {} 的 GestureDetector 包装构建器的结果。

showModalBottomSheet(
  context: context,
  builder: (context) => GestureDetector(
    child: **any_widget_here**,
    onVerticalDragStart: (_) {},
  ),
  isDismissible: false,
  isScrollControlled: true,
);

太聪明了:D 对于持久的底部表格,它完美地工作了,谢谢。 - Georg Panteleev
Flutter稳定通道的简单解决方案 - Alessandro Santamaria

3

如果您仍希望在模态框中使用滚动条但又不希望用户拖动和关闭它,可以使用以下代码:

                  showModalBottomSheet(
                    context: context,
                    enableDrag: false,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.vertical(
                        top: Radius.circular(20),
                      ),
                    ),
                    clipBehavior: Clip.antiAliasWithSaveLayer,
                    builder: (context) => DraggableScrollableSheet(
                      expand: false,
                      initialChildSize: 0.9,
                      minChildSize: 0.5,
                      maxChildSize: 0.9,
                      builder: (context, scrollController) {
                        return SingleChildScrollView(
                          child: new Container(
                            color: Colors.white,
                            child: buildTitleWidget(),
                          ),
                        );
                      },
                    ),
                    isDismissible: false,
                    isScrollControlled: true,
                  );

关键是不要将scrollController添加到SingleChildScrollView中。
                      builder: (context, scrollController) {
                        return SingleChildScrollView(
                          controller: scrollController            <-- HERE
                          child: new Container(
                            color: Colors.white,
                            child: buildTitleWidget(),
                          ),
                        );
                      },

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 提供, 点击上面的
可以查看英文原文,
原文链接