Flutter底部弹出框宽度如何改变?

6
我希望底部工作表看起来像 Angular Material 中的一个。
enter image description here 该工作表将扩展到最大宽度。问题在于我无法配置底部工作表的宽度。 目前它看起来像这样: enter image description here 我的代码如下:
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: ...,
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          tooltip: 'Add File',
          onPressed: () => showModalBottomSheet(
            context: context,
            builder: (context) => AddFileBottomSheet(),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(10),
                topRight: Radius.circular(10),
              ),
            ),
            // backgroundColor: Colors.transparent,
            isScrollControlled: true,
          ),
        ),
      ),
    );
  }
}

class AddFileBottomSheet extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Container(
            padding: EdgeInsets.symmetric(vertical: 20, horizontal: 5),
            alignment: Alignment.center,
            child: Text(
              'Create New File',
              style: Theme.of(context).textTheme.headline5,
            ),
          ),
          GridView.count(
            shrinkWrap: true,
            crossAxisCount: 3,
            children: [
              _gridTile(
                context: context,
                icon: Icon(Icons.file_upload),
                text: 'Upload File',
                callback: () => print('lel'),
              ),
              _gridTile(
                context: context,
                icon: Icon(Icons.create),
                text: 'Create Text File',
                callback: () => print('lel'),
              ),
            ],
          ),
        ],
    );
  }

  Widget _gridTile({
    @required BuildContext context,
    @required Icon icon,
    @required String text,
    @required void callback(),
  }) {
    return InkWell(
        onTap: () => callback(),
        child: Container(
          padding: EdgeInsets.all(15),
          alignment: Alignment.center,
          height: double.infinity,
          width: double.infinity,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              icon,
              Text(text, style: Theme.of(context).textTheme.subtitle2),
            ],
          ),
        ),
    );
  }
}

我知道可以通过将部分内容变为透明来模拟缩小宽度的效果,但是我有圆角,这些圆角就无法得到保留。

解决方法 #1

我成功地通过将widget中的canvasColor改为透明,并使边框呈现圆角来解决了这个问题: enter image description here 然而,这样做需要额外的逻辑来在用户单击假透明区域时关闭它。

首先要想办法将canvasColor添加到上下文中:

...
      floatingActionButton: Theme(
        data: Theme.of(context).copyWith(canvasColor: Colors.transparent),
        child: Builder(
          builder: (context) => FloatingActionButton(
            child: Icon(Icons.add),
            tooltip: 'Add File',
            onPressed: () => showModalBottomSheet(
              context: context,
              builder: (context) => AddFileBottomSheet(),
              // shape: RoundedRectangleBorder(
              //   borderRadius: BorderRadius.only(
              //     topLeft: Radius.circular(10),
              //     topRight: Radius.circular(10),
              //   ),
              // ),
              // backgroundColor: Colors.transparent,
              isScrollControlled: true,
            ),
          ),
        ),
      ),
...

然后伪造宽度

    return Container(
      padding: EdgeInsets.symmetric(horizontal: 300),
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white,
          shape: BoxShape.rectangle,
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(10),
            topRight: Radius.circular(10),
          ),
        ),
        // backgroundColor: Colors.transparent,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Container(
              padding: EdgeInsets.symmetric(vertical: 20, horizontal: 5),
              alignment: Alignment.center,
              child: Text(
                'Create New File',
                style: Theme.of(context).textTheme.headline5,
              ),
            ),
            GridView.count(
              shrinkWrap: true,
              crossAxisCount: 3,
              children: [
                _gridTile(
                  context: context,
                  icon: Icon(Icons.file_upload),
                  text: 'Upload File',
                  callback: () => print('lel'),
                ),
                _gridTile(
                  context: context,
                  icon: Icon(Icons.create),
                  text: 'Create Text File',
                  callback: () => print('lel'),
                ),
              ],
            ),
          ],
        ),
      ),
    );

我想知道是否有标准方法可供使用,需要您的帮助。我尝试创建一个DartPad示例,但它给了我一个脚本错误

我的想法是尝试使用类似以下内容的方式使其适用于移动设备:

    final isMobile = MediaQuery.of(context).size.width < 700;
    return Container(
      padding: EdgeInsets.symmetric(horizontal: isMobile ? 0: 300),
      child: ...
    )

这将使其在移动端时全屏显示,并在桌面端添加一些填充。


目前,向 showModalBottomSheet 添加 constraint 是正确的方法。 - James Poulose
3个回答

18

更新:Flutter现在在showModalBottomSheet中支持constraints属性。

showModalBottomSheet(
  context: context,
  constraints: BoxConstraints(
     maxWidth: Responsive.isMobile(context) ? Get.width : 600,              
  ),
  builder: ...
),

3

更新

Flutter在master、dev和beta版本中添加了对 showModalBottomSheet 的约束。


1
您可以将您的小部件用Align小部件包裹,并将对齐方式设置为底部中心,如果您想拥有最大宽度,那么您可以设置框约束。
Align(
  alignment: Alignment.bottomCenter,
  child: ConstrainedBox(
    constraints: BoxConstraints(...),
    child: ...
  ),
)

看起来很有前途,但我现在无法测试它。如果您确定它有效,我会接受您的答案。 - Dennis Barzanoff
是的,我和你一样遇到了同样的问题,因为我不想在平板电脑上使用全宽底部工作表。你可以试试自己做一天,谢谢。 - Pantelis Tsak
1
这个解决方案不起作用。我已经在Flutter存储库上创建了一个功能请求。希望一切顺利。 - Rebar

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