如何将小部件放置在SingleChildScrollView的底部?

时间:2019-03-08 16:32:58

标签: flutter flutter-layout

我需要使用SingleChildScrollView才能使用keyboard_actions,以便可以在iOS的键盘上方放置一个“完成”按钮(目前使用数字键盘)

SingleChildScrollView的子级将有一个列,然后在底部放置一个按钮。我尝试使用LayoutBuilder来增强SingleChildScrollView的高度。

LayoutBuilder(
      builder: (BuildContext context, BoxConstraints viewportConstraints) {
    return SingleChildScrollView(
        child: ConstrainedBox(
            constraints:
                BoxConstraints(minHeight: viewportConstraints.maxHeight),
            child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                mainAxisSize: MainAxisSize.max,
                children: <Widget>[
                  Column(),
                  // Spacer() ?
                  FlatButton()
                ])));
  });

我尝试将BoxConstraintsmaxHeight属性一起使用,但是最终当键盘出现时,该小部件不会被覆盖。

旁注:脚手架将resizeToAvoidBottomInsetresizeToAvoidBottomPadding都设置为true(默认值)

4 个答案:

答案 0 :(得分:6)

选择的答案并没有真正起作用,因为使用SizedBox将Column的最大大小限制为屏幕的高度,因此您无法在其中放入任意数量的小部件(否则它们将消失)屏幕,而不会滚动)。

无论该列中有许多小部件,该解决方案都将起作用: https://github.com/flutter/flutter/issues/18711#issuecomment-505791677

重要说明:仅当列中的窗口小部件具有固定高度(例如TextInputField不具有固定高度)时,它才有效。如果它们的高度可变,则用固定高度的容器包装它们。

答案 1 :(得分:3)

SingleChildScrollView的问题在于shrikwrap是孩子。 因此,要在两者之间使用自动尺寸小部件-我们需要使用MediaQuery来获取屏幕高度,并使用SizedBox来扩展屏幕-SingleChildScrollView

此处按钮位于屏幕底部。

工作代码:

double height = MediaQuery.of(context).size.height;

    SingleChildScrollView(
          child: SizedBox(
              height: height,
              child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  mainAxisSize: MainAxisSize.max,
                  children: <Widget>[
                    Column(
                      children: <Widget>[
                        Text('Dummy'),
                        Text('Dummy'),
                        Text('Dummy'),
                      ],
                    ),
                    Spacer(),
                    FlatButton(
                      onPressed: () {},
                      child: Text('Demo'),
                    )
                  ])),
        ) 

答案 2 :(得分:1)

您也可以使用此解决方法,您可以在 SingleChildScrollView 中使用 padding 属性,如下所示:

SingleChildScrollView(
padding: EdgeInsets.only(top: height),
child: yourWidgets(),

而高度是离顶部的距离。
您还可以使用此行获取移动屏幕高度:

double height = MediaQuery.of(context).size.height;

答案 3 :(得分:1)

我刚刚复制并粘贴了我找到的最佳解决方案,由@Quentin 引用,由@NikitaZhelonkin 在 Github 上 Flutter 的第 18711 期详细阐述。简直就是完美的解决方案!

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('AppBar'),
        ),
        body: LayoutBuilder(builder: (context, constraints) {
          return SingleChildScrollView(
              child: ConstrainedBox(
                  constraints: BoxConstraints(minWidth: constraints.maxWidth, minHeight: constraints.maxHeight),
                  child: IntrinsicHeight(
                    child: Column(
                        mainAxisSize: MainAxisSize.max,
                        children: [
                          Text('header'),
                          Expanded(
                            child: Container(
                              color: Colors.green,
                              child: Text('body'),
                            ),
                          ),
                          Text('footer'),
                        ]
                    ),
                  )
              )
          );
        })
    );
  }
}