如何在Flutter中创建一个带圆角的模态底片?

Her*_*man 14 flutter flutter-layout

showModalBottomSheet不提供任何样式或装饰.我想创建类似Google Tasks底片的内容.

谷歌任务底部表格

Sha*_*Ali 59

showModalBottomSheet(
context:context
shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(
          top: Radius.circular(20),
        ),
      ),
      clipBehavior: Clip.antiAliasWithSaveLayer,
)
Run Code Online (Sandbox Code Playgroud)

  • `Clip.antiAliasWithSaveLayer` 使得如果模态表的内容是可滚动的,如果有人想知道的话,可滚动内容也将被剪切到模态的边框半径。 (5认同)
  • 如果您解释了您提供的代码如何回答问题,这将是一个更好的答案。 (2认同)
  • 这应该被接受,因为它不需要全局设置画布颜色。它更简洁 (2认同)

npa*_*ace 34

我认为做圆角模态的最好方法是使用 aRoundedRectangleBorder和一个 vertical BorderRadius,只设置它的top属性:

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

对左上角和右上角使用单独的半径有点冗长且容易出错。


Gil*_*lho 31

而不是覆盖应用程序的整个主题(这导致我的应用程序的各个部分出现问题),而不是其他答案所建议的,我决定看看实现showModalBottomSheet并自己找到问题.事实证明,所需要的只是在ShapeBorder包含backgroundColor技巧的小部件中包含模式的主代码.我还更容易定制半径以及模态本身的颜色.

您可以使用pub上的或包含相同代码的要点.不要忘记导入正确的包/文件.

showModalBottomSheet(
  shape: RoundedRectangleBorder(
     borderRadius: BorderRadius.circular(10.0),
  ),
  backgroundColor: Colors.white,
  ...
);
Run Code Online (Sandbox Code Playgroud)


小智 28

这是所需的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"),
                    )),
              );
            }
        );
      }
Run Code Online (Sandbox Code Playgroud)

此工作正常工作中最重要的部分是,在MaterialApp中将canvasColor设置为透明,如下所示.

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

我已经测试了代码并且它工作得很好,因为我也正在克隆Google Tasks应用程序,它将在我的github中开源.

  • 更改bottomSheet圆角的全局“canvasColor”并不是一个好的权衡。使用“Theme”包装器代替。另外,如果底部工作表内的小部件取决于主题,则使用“data: yourTheme().copyWith(canvasColor: Colors.transparent)”仅将画布颜色仅应用于其子项。最好的选择是更新的。 (11认同)

use*_*714 15

我有这个代码,对我来说效果很好。请检查一下,让我知道你的意见。

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"),
                    )),
              ))
Run Code Online (Sandbox Code Playgroud)


fee*_*nda 13

将形状设置为RoundedRectangleBorder应该可以,但有时内容会溢出,导致圆角丢失,当发生这种情况时,将 ClipBehavior 设置为 Clip.antiAlias即可解决。

showModalBottomSheet(
    isScrollControlled: true,
    backgroundColor: colorOnPrimary,
    // set this when inner content overflows, making RoundedRectangleBorder not working as expected
    clipBehavior: Clip.antiAlias,
    // set shape to make top corners rounded
    shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
            topLeft: Radius.circular(16), 
            topRight: Radius.circular(16),
        ),
    ),
    context: context,
    builder: (context) {
        return SingleChildScrollView(
            child: Container(),
        );
    },
)
Run Code Online (Sandbox Code Playgroud)


小智 12

一种方法是使用showModalBottomSheet shape财产,

showModalBottomSheet(
  context:context
  shape: const RoundedRectangleBorder(
    borderRadius: BorderRadius.only(
      topLeft: Radius.circular(10.0),
      topRight: Radius.circular(10.0),
    ),
  ),
)
Run Code Online (Sandbox Code Playgroud)


Sve*_*ven 9

现在,您可以简单地设置shape参数。例:

showModalBottomSheet(
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.all(Radius.circular(10.0)),
  ),
  context: context,
  builder: (context) => MyBottomSheet(),
);
Run Code Online (Sandbox Code Playgroud)


小智 6

RoundedRectangleBorder您可以在以下位置添加小部件showModalBottomSheet

showModalBottomSheet<void>(
    shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
            topLeft: Radius.circular(10.0),
            topRight: Radius.circular(10.0)
        ),
    ),
)
Run Code Online (Sandbox Code Playgroud)


小智 5

将之前的所有答案放在一起,我可以为此获得最好的结果(在我看来)。

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');
                  },
               ),                  
            ],
          );
        });
Run Code Online (Sandbox Code Playgroud)