Как создать модальный нижний лист с круглыми углами во Flutter?

showModalBottomSheet не предоставляет никаких стилей или украшений. Я хочу создать что-то вроде нижней таблицы Задач Google.

Нижняя таблица задач Google


person Herman    schedule 16.05.2018    source источник


Ответы (10)


Это необходимая функция modalBottomSheet.

    void _modalBottomSheetMenu(){
        showModalBottomSheet(
            context: context,
            builder: (builder){
              return new Container(
                height: 350.0,
                color: Colors.transparent, //could change this to Color(0xFF737373), 
                           //so you don't have to change MaterialApp canvasColor
                child: new Container(
                    decoration: new BoxDecoration(
                        color: Colors.white,
                        borderRadius: new BorderRadius.only(
                            topLeft: const Radius.circular(10.0),
                            topRight: const Radius.circular(10.0))),
                    child: new Center(
                      child: new Text("This is a modal sheet"),
                    )),
              );
            }
        );
      }

Также наиболее важной частью правильной работы является то, что в MaterialApp установите для свойства canvasColor значение transparent, как показано ниже.

return new MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Tasks',
      theme: new ThemeData(
        primarySwatch: Colors.teal,
        canvasColor: Colors.transparent,
      ),
      home: new TasksHomePage(),
    );
  }

Я протестировал код, и он отлично работает, так как я также делал клон приложения Google Tasks, исходный код которого будет открыт в моем github < / а>.

person Satyabrat Sahoo    schedule 09.06.2018

ОБНОВЛЕНО 2019-08-05

Теперь вы можете сделать это, используя метод showModalBottomSheet по умолчанию, который теперь поддерживает добавление ShapeBorder, а также backgroundColor!

showModalBottomSheet(
  shape: RoundedRectangleBorder(
     borderRadius: BorderRadius.circular(10.0),
  ),
  backgroundColor: Colors.white,
  ...
);

--

Вместо того, чтобы переопределить всю тему приложения (что вызывало проблемы в различных частях моего приложения), как было предложено другими ответами, я решил взглянуть на реализацию для showModalBottomSheet и сам найти проблему. Оказывается, все, что было нужно, - это обернуть основной код модального окна в виджет Theme, содержащий трюк canvasColor: Colors.transparent. Я также упростил настройку радиуса, а также цвета самого модального окна.

Вы можете использовать либо пакет в pub, либо gist, содержащий тот же код. Не забудьте импортировать нужный пакет / файл.

showRoundedModalBottomSheet(
    context: context,
    radius: 20.0,  // This is the default
    color: Colors.white,  // Also default
    builder: (context) => ???,
);
person Gildásio Filho    schedule 31.08.2018
comment
+1. Для меня было недостаточно обернуть только кнопку, содержащую метод отображения модальной панели. Но обертывание эшафота, содержащего экран, такой темой сработало. @override Widget build(BuildContext context) { return Theme( // We need this theme override so that the corners of the bottom sheet modal can be rounded data: ThemeData(canvasColor: Colors.transparent), child: Scaffold( .... - person Simon Olsen; 01.04.2019

Я думаю, что лучший способ сделать модальное окно с закругленными углами - использовать RoundedRectangleBorder с вертикальным BorderRadius, установив только его свойство top:

showModalBottomSheet(
        context: context,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.vertical(top: Radius.circular(25.0)),
        ),
        builder: (BuildContext context) {
          // return your layout
        });

Использование отдельных радиусов для верхнего левого и верхнего правого угла может быть более подробным и подверженным ошибкам.

person npace    schedule 05.01.2020
comment
Очень просто, спасибо! - person Messou; 27.07.2021

Теперь вы можете просто установить аргумент shape. Пример:

showModalBottomSheet(
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.all(Radius.circular(10.0)),
  ),
  context: context,
  builder: (context) => MyBottomSheet(),
);
person Sven    schedule 13.05.2019

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

showBottomSheet(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.vertical(
              top: Radius.circular(20),
            ),
          ),
          context: context,
          builder: (context) => Container(
                height: 250,

                child: new Container(
                    decoration: new BoxDecoration(
                        color: Theme.of(context).primaryColor,
                        borderRadius: new BorderRadius.only(
                            topLeft: const Radius.circular(20.0),
                            topRight: const Radius.circular(20.0))),
                    child: new Center(
                      child: new Text("This is a modal sheet"),
                    )),
              ))
person mohammad mobasher    schedule 26.02.2020
comment
Я пользуюсь этим, и это работает !!! спасибо @mohammad, ты спас мне день. - person Hengki Lodwig; 07.04.2021
comment
Добро пожаловать :) - person mohammad mobasher; 04.05.2021

Собрав все ответы воедино, я смог добиться для этого наилучшего, на мой взгляд, результата.

showModalBottomSheet(
        context: context,
        backgroundColor: Colors.white,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.only(topLeft: Radius.circular(15.0), topRight: Radius.circular(15.0)),
        ),
        builder: (context) {
          return Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[     
              ListTile(
                leading: Icon(Icons.email),
                title: Text('Send email'),
                onTap: () {
                  print('Send email');
                },
              ),
              ListTile(
                leading: Icon(Icons.phone),
                title: Text('Call phone'),
                 onTap: () {
                    print('Call phone');
                  },
               ),                  
            ],
          );
        });
person Carlos Eugênio Torres    schedule 13.09.2019

Вы можете добавить виджет RoundedRectangleBorder внутри showModalBottomSheet:

showModalBottomSheet<void>(
    shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
            topLeft: Radius.circular(10.0),
            topRight: Radius.circular(10.0)
        ),
    ),
)
person Chamindu Weerasinghe    schedule 19.01.2021

Только что ответил на связанный вопрос

Вы можете добавить углы к вашему bottomSheet и расширить bottomSheet в соответствии с содержимым, присутствующим внутри него (не ограничиваясь половиной размера экрана)

ознакомьтесь с ответом здесь

https://stackoverflow.com/a/59541927/9236994

person Vicky Salunkhe    schedule 31.12.2019

Вы также можете указать borderRadius в контейнере украшения.

 showModalBottomSheet(
                context: context,
                builder: (builder){
                  return  Container(
                        decoration: BoxDecoration(
                            color: Colors.white,
                            borderRadius: BorderRadius.only(
                                topLeft: const Radius.circular(15.0),
                                topRight: const Radius.circular(15.0))),
                        child: Center(
                          child: Text("This is a modal sheet"),
                        ),
                  );
                }
            );
person Shrey Jain    schedule 06.02.2021

person    schedule
comment
Было бы лучше, если бы вы объяснили, как предоставленный вами код отвечает на вопрос. - person pppery; 19.06.2020
comment
Лучший ответ Спасибо. - person abrsh; 15.09.2020
comment
здорово, спасибо - person Milan Varasada; 02.12.2020
comment
это должен быть принятый ответ, поскольку он не требует глобальной настройки цвета холста. это более лаконично - person laszlo; 14.04.2021
comment
Clip.antiAliasWithSaveLayer делает так, что если содержимое модального листа можно прокручивать, прокручиваемое содержимое также будет обрезано до радиуса границы модального окна, если кому-то интересно. - person テッド; 19.07.2021