带列的 SingleChildScrollView,底部需要按钮

Posted

技术标签:

【中文标题】带列的 SingleChildScrollView,底部需要按钮【英文标题】:SingleChildScrollView with Column, need button at bottom 【发布时间】:2019-11-09 20:53:56 【问题描述】:

我正在尝试创建一个包含一列的 SingleChildScrollView,并且我希望一个按钮位于屏幕的最底部。为此,我尝试使用具有 SingleChildScrollView 和 FlatButton 的堆栈作为子级。我最终得到的是:

即使我已定位按钮并将其与底部对齐,我也无法让按钮粘在底部。绿色只是为了显示柱子的高度,并且按钮被卡在柱子的底部。 Stack、SingleChildScrollView、Column 和 FlatButton 只占用它们显示所需的空间。我需要将该按钮粘贴到屏幕底部。

这是我用来创建它的代码。我错过了什么?

return Scaffold(
  appBar: AppBar(
    // Here we take the value from the MyHomePage object that was created by
    // the App.build method, and use it to set our appbar title.
    title: Text(widget.title),
  ),
  body: Container(
    width: double.infinity,
    color: Colors.red,
    child: Stack(
      children: <Widget>[
        Container(
          color: Colors.green,
          child: SingleChildScrollView(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                Container(
                  child: TextField(
                    decoration: InputDecoration(
                      labelText: 'Protein',
                    ),
                  ),
                  margin: EdgeInsets.only(left: 20, right: 20),
                ),
                Container(
                  child: TextField(
                    decoration: InputDecoration(
                      labelText: 'Fat',
                    ),
                  ),
                  margin: EdgeInsets.only(left: 20, right: 20),
                ),
                Container(
                  child: TextField(
                    decoration: InputDecoration(
                      labelText: 'Fiber',
                    ),
                  ),
                  margin: EdgeInsets.only(left: 20, right: 20),
                ),
                Container(
                  child: TextField(
                    decoration: InputDecoration(
                      labelText: 'Moisture',
                    ),
                  ),
                  margin: EdgeInsets.only(left: 20, right: 20),
                ),
                Container(
                  child: TextField(
                    decoration: InputDecoration(
                      labelText: 'Ash',
                    ),
                  ),
                  margin: EdgeInsets.only(left: 20, right: 20),
                ),
              ],
            ),
          ),
        ),
        Positioned(
          bottom: 0,
          left: 0,
          right: 0,
          child: Align(
            alignment: Alignment.bottomCenter,
            child: ButtonTheme(
              minWidth: double.infinity,
              height: 50,
              child: FlatButton(
                color: Colors.blueAccent.shade400,
                onPressed: () ,
                child: Text(
                  'Calculate Carbs',
                  style: TextStyle(
                    fontSize: 20,
                    color: Colors.white,
                  ),
                ),
              ),
            ),
          ),
        )
      ],
    ),
  ),
);

编辑:下面给出的两种方法都可以扩展堆栈以填满整个屏幕。我添加了额外的 TextField 小部件来填满屏幕,然后单击底部的小部件以确保底部小部件在键盘打开时可见,并注意到按钮覆盖了底部字段。就像滚动视图正在向上滚动正确的数量一样,忽略了那里有一个按钮。

在下面的图片中,我点击了 End Field 3 小部件。按钮盖住了它,所以我看不到我正在输入的内容。

【问题讨论】:

您可能已经解决了这个问题,但以防万一,您可以在脚手架上使用 `resizeToAvoidBottomInset: false` 来避免这种情况 你是怎么解决这个问题的?我正在努力解决同样的问题。手动设置高度会破坏文本输入的 scolling 【参考方案1】:

带有浮动操作按钮的选项 1

@override
  Widget build(BuildContext context) 
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(),
      ),
      floatingActionButton: YourButtonWidget(),
      floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
    );
  

带有底部导航栏的选项 2

@override
  Widget build(BuildContext context) 
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(),
      ),
      bottomNavigationBar: YourButtonWidget(),
    );
  

【讨论】:

这个解决方案有效,但假设我们有一个行小部件,那么它不会弯曲整个宽度 @RishabhAgrawal 为此包装行 SizedBox 并将全宽分配给 sizebox【参考方案2】:

使用CustomScrollView:

CustomScrollView(
  slivers: [
    SliverFillRemaining(
      hasScrollBody: false,
      child: Column(
        children: <Widget>[
          const Text('Header'),
          Expanded(child: Container(color: Colors.red)),
          const Text('Footer'),
        ],
      ),
    ),
  ],
)

见:https://***.com/a/62097942/5164462

【讨论】:

【参考方案3】:

这种行为的原因是父容器的大小。只需更改容器大小

      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        color: Colors.red,
        child: Stack(
          children: <Widget>[

你就完成了。

解释,如果你好奇:) 如果我们查看 Stack 小部件,我们可以找到此描述

   /// By default, the non-positioned children of the stack are aligned by their
  /// top left corners.

所以,这个小部件只占用父小部件提供的空间。你使用了没有尺寸的容器。所有子小部件都自动取代了它们的位置,Alin 在这个自动创建的容器中工作。

【讨论】:

【参考方案4】:

将按钮始终保持在底部,

@override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Column(
        children: [
          Expanded(
              child: Padding(
                padding: const EdgeInsets.all(15.0),
                child: new Form(
                  key: _formKey, 
                  child: SingleChildScrollView(
                    child: Column(
                      children: [
                         _currntForm()
                      ],
                    )
                  )),
              )),
           Padding(
            padding: const EdgeInsets.all(15.0),
            child: FullWidthIconBotton(
              icon: Icon(LinearIcons.floppy_disk),
              label: 'SAVE',
              color: Colors.green,
              onClick: () 
                _validateFormFields();
              ,
            ) ,
          ) 
        ],
      ),
    );
  

【讨论】:

【参考方案5】:

将此参数添加到堆栈中:fit: StackFit.expand,

【讨论】:

以上是关于带列的 SingleChildScrollView,底部需要按钮的主要内容,如果未能解决你的问题,请参考以下文章

Postgres获取带列的表架构

如何在jqGrid中禁用所选列的搜索选项?

Pandas:转换列的类型

Flutter:SingleChildScrollView 内的 TabBarView

SingleChildScrollView ,子列上的空格问题

Flutter 可滚动组件 之 SingleChildScrollView (十五)