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

Mar*_*ary 7 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
      },
    );
}
Run Code Online (Sandbox Code Playgroud)

我试过了:

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

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

Vic*_*khe 91

默认高度bottomSheet是 screenSize 的一半

如果您希望bottomSheet根据您的内容动态扩展

使用下面的代码

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

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

用于 在代码下方bottomSheet返回顶部添加半径到“bottomSheet”

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

满足这两个要求的完整代码

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

  • 如果Wrap中有一个ListView,它将无法滚动。如果我将Wrap替换为Column,就会溢出。为什么? (4认同)
  • 要在顶部添加半径,我更喜欢将其添加到模态的形状属性上。形状:RoundedRectangleBorder(borderRadius:BorderRadius.vertical(顶部:Radius.circular(12))), (4认同)
  • @RaviParmar我非常确定,当您将“ListView.shrinkWrap”设置为“true”或在“Expanded”内部(后者取决于父级和兄弟级)时,它确实允许将其放置在几乎任何地方。无论如何,我只是在 @parcool 提到的内容中提到了这一点,这并不是对此答案的建议。 (2认同)

far*_*ali 53

这是可能的

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"),
    ),
  ),
);
Run Code Online (Sandbox Code Playgroud)
  1. 设置isScrollControlled: truebackgroundColor: Colors.transparent为模态
  2. 向模态构建器提供Container所需的height:根小部件
  3. 提供BoxDecoration所需borderRadiusContainer

示例截图

  • 这正如预期的那样工作正常:) (2认同)

小智 16

要更改底片的高度,最好使用底片的constraintsisScrollControlled属性。

像这样:

showModalBottomSheet(
  constraints: BoxConstraints.loose(Size(
            MediaQuery.of(context).size.width,
            MediaQuery.of(context).size.height * 0.75)), // <= this is set to 3/4 of screen size.
  isScrollControlled: true, // <= set to true. setting this without constrains may cause full screen bottomsheet.
  context: context,
  builder: (context) => yourWidget()
);
Run Code Online (Sandbox Code Playgroud)

对于边界半径,请使用以下shape属性:

showModalBottomSheet(
  shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(top: Radius.circular(45))), // <= set preferable radius.
  context: context,
  builder: (context) => yourWidget()
);
Run Code Online (Sandbox Code Playgroud)


mah*_*mnj 11

您可以使用 SingleChildScrollView 内的 Column 来动态更改底部工作表的高度,并且一旦超过可用的最大高度,它就会变得可滚动,确保将isScrollControlled其设置为 true,对于边框半径,该shape属性将帮助您添加 borderRadius到底片。这是相同的飞镖示例


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

Run Code Online (Sandbox Code Playgroud)


Eri*_*eni 8

根据 Vicky 的回答,Wrap可能会让对齐变得痛苦。Column(mainAxisSize: MainAxisSize.min, children: [...])在小部件中使用。在您的示例中实现它应该如下所示:

void _showBottomSheet(BuildContext context) {
    showModalBottomSheet<Null>(
      context: context,
      builder: (BuildContext context) {
        return Column(
        mainAxisAxisSize: MainAxisSize.min,
        children: [
          _bottomSheetScreen
        ]); // defined earlier on
      },
    );
}
Run Code Online (Sandbox Code Playgroud)

如果您想通过滑动控制滚动,请尝试isScrollControlled: trueshowModalBottomSheet().


Shy*_*hil 7

使用showBottomSheet而不是 showModalBottomSheet

创建全局密钥和侦听器

final _scaffoldKey = new GlobalKey<ScaffoldState>();
VoidCallback _showPersBottomSheetCallBack;
Run Code Online (Sandbox Code Playgroud)

编写您的方法来显示工作表

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

初始化监听器

void initState() {
    super.initState();
    _showPersBottomSheetCallBack = _showBottomSheet;
  }
Run Code Online (Sandbox Code Playgroud)

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

new RaisedButton(
                  onPressed: _showPersBottomSheetCallBack,
                  child: new Text("Persistent"),
                ),
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你 !


rya*_*sh7 7

最近我找到了一个解决方法。通过在您的应用程序主题中设置canvasColor属性Colors.transparent,我们可以使BottomSheet 的覆盖层消失。

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

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

带圆角的底板


Tom*_*ran 7

不需要包裹任何东西。只设置:

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

Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明 在此处输入图片说明


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

  • 应用解决方案时,当底部工作表超出指定的约束高度时,拖动以关闭底部工作表将不起作用 (4认同)

Dav*_*ara 6

这是 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
      });
Run Code Online (Sandbox Code Playgroud)


Jay*_*gra 5

使用下面的代码

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


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

showModalBottomSheet<dynamic>(
isScrollControlled: true,
context: context,
builder: (BuildContext bc) {
  return YourWidget();
 }
)
Run Code Online (Sandbox Code Playgroud)