Отключить перетаскивание, чтобы закрыть showModalBottomSheet

Как отключить / убрать жест перетаскивания в модале нижнего листа, чтобы пользователь мог взаимодействовать в модале, не закрывая модально случайно?

4 ответа

Задавать enableDrag в false

bool enableDrag

Если это правда, нижний лист можно перетаскивать вверх и вниз и отклонять, проводя вниз.

https://docs.flutter.io/flutter/material/BottomSheet/enableDrag.html

Вы можете попробовать обернуть результат построителя с помощью GestureDetector с onVerticalDragStart = (_) {}

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

Если вы все еще хотите, чтобы прокрутка была внутри модального окна без перетаскивания и закрытия пользователем, вы можете использовать это:

                        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(),
                          ),
                        );
                      },

Мне нужен нижний лист, который можно перетаскивать вверх и вниз, но который не закрывается при перетаскивании вниз. Я подумал, что если, как только он закроется, я позвоню ему снова? Здесь на помощь приходит рекурсия. Итак, прежде всего я создал функцию для моего modalBottomSheet.

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

Затем я использовал метод .whenComplete() функции showModalBottomSheet() для рекурсивного вызова функции 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));
  }
}
Другие вопросы по тегам