如何在Flutter中调整BottomSheet的高度和borderRadius?

时间:2018-02-24 22:15:05

标签: material-design flutter bottom-sheet

我可能在这里遗漏了一些明显的东西,但我的BottomSheet只占据了屏幕的下半部分,即使它中的小部件占用更多空间。所以现在BottomSheet中有滚动行为。我希望能够增加BottomSheet,以便用户不必滚动太多。

我还想在我的BottomSheet的顶部添加一个borderRadius,使它看起来更像“模态”-y或“tab”一样。

代码:

void _showBottomSheet(BuildContext context) {
    showModalBottomSheet<Null>(
      context: context,
      builder: (BuildContext context) {
        return _bottomSheetScreen; // defined earlier on
      },
    );
}

我试过了:

showModalBottomSheet<Null>(
  context: context,
  builder: (BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        borderRadius: _borderRadius,
      ),
      height: 1000.0,
      child: _bottomSheetScreen,
    );
  },
);

但似乎只会影响BottomSheet中的内容,并且不会自定义BottomSheet本身。

12 个答案:

答案 0 :(得分:31)

有可能这样

showModalBottomSheet(
  context: context,
  isScrollControlled: true,
  backgroundColor: Colors.transparent,
  builder: (context) => Container(
    height: MediaQuery.of(context).size.height * 0.75,
    decoration: new BoxDecoration(
      color: Colors.white,
      borderRadius: new BorderRadius.only(
        topLeft: const Radius.circular(25.0),
        topRight: const Radius.circular(25.0),
      ),
    ),
    child: Center(
      child: Text("Modal content goes here"),
    ),
  ),
);
  1. 为模态设置isScrollControlled: truebackgroundColor: Colors.transparent
  2. 为模态构建器提供Container作为必需的height:作为根窗口小部件
  3. BoxDecoration提供borderRadius和必需的Container

Sample Screenshot

答案 1 :(得分:5)

无需包装任何东西。只设置:

  • isScrollControlled: trueshowModalBottomSheet
  • shrinkWrap: true,ListView

这是最小的通用代码:

import 'package:flutter/material.dart';

Future<Widget> show123(BuildContext context) {
  return showModalBottomSheet<dynamic>(
      useRootNavigator: true,
      isScrollControlled: true,
      context: context,
      builder: (BuildContext bc) {
        return ListView(
          shrinkWrap: true,
          children: [
            ListItem(),
            ListItem(),
            ListItem(),
          ],
        );
      });
}

您可以从我的案例中获得启发,这取决于 AlbumRow 的数量动态。如果高度达到最大值,您可以通过滚动到达底部。

enter image description here enter image description here


import 'package:flutter/material.dart';

Future<Widget> showBottomSheet(BuildContext context) {
  return showModalBottomSheet<dynamic>(
      useRootNavigator: true,
      barrierColor: Colors.black.withOpacity(0.5),
      isScrollControlled: true,
      context: context,
      builder: (BuildContext bc) {
        return ConstrainedBox(
          constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height * 0.9),
          child: Container(
            decoration: new BoxDecoration(
                color: Colors.blue, borderRadius: new BorderRadius.only(topLeft: const Radius.circular(25.0), topRight: const Radius.circular(25.0))),
            child: ListView(
              shrinkWrap: true,
              children: [
                Padding(
                  padding: const EdgeInsets.fromLTRB(30, 30, 30, 45),
                  child: Text(
                    'Choose Album',
                    textAlign: TextAlign.center,
                  ),
                ),
                AlbumRow(title: 'For Weekends arta iretnairstnaisetn aistn aisetn'),
                AlbumRow(title: 'Creative'),
                AlbumRow(title: 'Christmas'),
                AlbumRow(title: 'For Weekends arta iretnairstnaisetn aistn aisetn'),
              ],
            ),
          ),
        );
      });
}

答案 2 :(得分:4)

使用下面的代码

注意:如果您使用的是列,则使用 ma​​inAxisSize: MainAxisSize.min


// make isScrollControlled : true
// if using column then make - mainAxisSize: MainAxisSize.min

showModalBottomSheet<dynamic>(
isScrollControlled: true,
context: context,
builder: (BuildContext bc) {
  return YourWidget();
 }
)

答案 3 :(得分:4)

您可以通过设置 isScrollControlled: true 并将 BottomSheet 包裹在 FractionallySizedBox 中来调整高度。它看起来像这样:

 showModalBottomSheet<void>(
    context: context,
    //This
    isScrollControlled: true,
    builder: (BuildContext context) {
      return StatefulBuilder(
          builder: (BuildContext context, StateSetter state) {
        return FractionallySizedBox(
            //Here specify the high of the BottomSheet
            heightFactor: 0.9,
            child:BottomSheet(
            .
            .
            .
            
            .
            .
            .
      ));
      });
    });

答案 4 :(得分:3)

使用 showBottomSheet 代替showModalBottomSheet

创建全局密钥和监听器

final _scaffoldKey = new GlobalKey<ScaffoldState>();
VoidCallback _showPersBottomSheetCallBack;

编写您的方法以显示表格

  void _showBottomSheet() {
    setState(() {
      _showPersBottomSheetCallBack = null;
    });

    _scaffoldKey.currentState
        .showBottomSheet((context) {
      return new Container(
        height: MediaQuery.of(context).size.height-100.0,
        color: Colors.greenAccent,
        child: new Center(
          child: new Text("Hi BottomSheet"),
        ),
      );
    })
        .closed
        .whenComplete(() {
      if (mounted) {
        setState(() {
          _showPersBottomSheetCallBack = _showBottomSheet;
        });
      }
    });
  }

初始化监听器

void initState() {
    super.initState();
    _showPersBottomSheetCallBack = _showBottomSheet;
  }

在任何需要的地方调用方法

new RaisedButton(
                  onPressed: _showPersBottomSheetCallBack,
                  child: new Text("Persistent"),
                ),

希望它有所帮助!

答案 5 :(得分:3)

最近我找到了解决方法。通过在应用主题中将canvasColor属性设置为Colors.transparent,我们可以让BottomSheet的叠加层消失。

return new MaterialApp(
  title: 'MyApp',
  theme: new ThemeData(
    primarySwatch: Colors.blue,
    canvasColor: Colors.transparent,
  ),
  //...
);

设置完毕后,您可以使用带圆角的ClipRRect或装饰。

Bottomsheet with rounded corners

答案 6 :(得分:2)

这里是 2021 年最简单的代码

 showModalBottomSheet(
      context: context,
      isScrollControlled: true,  // <-- make bottom sheet resize to content height
      shape: RoundedRectangleBorder(  // <-- for border radius
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(15.0),
          topRight: Radius.circular(15.0),
        ),
      ),
      builder: (BuildContext context) {
       return Container() // <-- any widget you want
      });

答案 7 :(得分:1)

您可以在SingleChildScrollView中使用Column来动态更改底部工作表的高度,并且一旦超过可用的最大高度,它也可以滚动,请确保isScrollControlled设置为true, 对于边界半径,shape属性将帮助您将borderRadius添加到底表。 这是dartpad example的代表


  Future<void> _showBottomSheet() async {
    return showModalBottomSheet(
      isScrollControlled: true,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(13)),
      backgroundColor: Colors.white,
      context: context,
      builder: (context) => SingleChildScrollView(
          child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: List.generate(kBoxes, (index) => _squareBox(index)))),
    );
  }

答案 8 :(得分:1)

简单的方法:

showModalBottomSheet(
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.only(
                          topRight: Radius.circular(15),
                          topLeft: Radius.circular(15),
                        ),
                      ),
                      context: context,
                      builder: (context) {
                        return Wrap(
                          children: [
                            Container(
                              height: 40,
                              child: Center(
                                child: Text(
                                  "Edit Profile",
                                  style: TextStyle(
                                    fontWeight: FontWeight.bold,
                                  ),
                                ),`
                              ),
                            ),                           
                          ],
                        );
                      });

答案 9 :(得分:0)

在@Shyju Madathil的上述代码中,您需要在脚手架中添加密钥以使其正常工作

return new Scaffold(
  key: _scaffoldKey,
  ....

答案 10 :(得分:0)

bottomSheet的默认高度是screenSize的一半

如果您希望 bottomSheet根据内容进行扩展

使用以下代码

showModalBottomSheet<dynamic>(
isScrollControlled: true,
context: context,
builder: (BuildContext bc) {
  return Wrap(
      children: <Widget>[...]
  )
 }
)

这将根据里面的内容自动展开bottomSheet

bottomSheet顶部添加半径,请在下面的代码中返回“ bottomSheet”

Container(
  color: forDialog ? Color(0xFF737373) : Colors.white,
  child: Container(
    decoration: new BoxDecoration(
    color: Colors.white,
      borderRadius: new BorderRadius.only(
            topLeft: const Radius.circular(25.0),
            topRight: const Radius.circular(25.0))),
      child: yourWidget(),
   ),
)

满足两个要求的完整代码

showModalBottomSheet<dynamic>(
isScrollControlled: true,
context: context,
builder: (BuildContext bc) {
  return Wrap(
      children: <Widget>[
          Container(
               color: forDialog ? Color(0xFF737373) : Colors.white,
                 child: Container(
                  decoration: new BoxDecoration(
                  color: Colors.white,
                    borderRadius: new BorderRadius.only(
                          topLeft: const Radius.circular(25.0),
                          topRight: const Radius.circular(25.0))),
                    child: yourWidget(),
                 ),
              )
      ]
   )
 }
)

答案 11 :(得分:0)

您可以通过设置主容器的高度来调整高度,该高度可以为常数ex:800或使用MediaQuery ex:

如果我只想显示屏幕的2/3

MediaQuery.of(context).size.height -
      (MediaQuery.of(context).size.height / 3)

首先要设置半径

 showModalBottomSheet(
                          backgroundColor: Colors.transparent,

然后将容器颜色设置为白色或所需的任何颜色,例如:

return Container(
  decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.only(
          topLeft: const Radius.circular(16),
          topRight: const Radius.circular(16))),
  child: