flutter 带列的SingleChildScrollView,底部需要按钮

9cbw7uwe  于 2023-01-27  发布在  Flutter
关注(0)|答案(7)|浏览(193)

我尝试创建一个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,
                  ),
                ),
              ),
            ),
          ),
        )
      ],
    ),
  ),
);

编辑:下面给出的两种方法都可以扩展Stack以填充整个屏幕。我添加了额外的TextField小部件来填充屏幕,然后单击底部的小部件以确保当键盘打开时底部的小部件可见,并注意到按钮覆盖了底部的字段。这就像滚动视图向上滚动了正确的量,而忽略了那里有一个按钮。
在下面的图片中,我点击了End Field 3小部件,按钮覆盖了它,所以我看不到我在字段中输入的内容。
第一节第一节第一节第二节第一节

voase2hg

voase2hg1#

使用CustomScrollView

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

参见:https://stackoverflow.com/a/62097942/5164462

w9apscun

w9apscun2#

带浮动操作按钮的选项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(),
    );
  }
bwntbbo3

bwntbbo33#

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

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在这个自动创建的容器中工作。

8ftvxx2r

8ftvxx2r4#

把按钮一直放在底部,

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

cvxl0en25#

我通过捕捉键盘显示和调整高度的容器,如果键盘显示解决了这个问题

bool isKeyboardShowing = MediaQuery.of(context).viewInsets.vertical > 0;
@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: Container(
          height: isKeyboardShowing
              ? MediaQuery.of(context).size.height - 100
              : MediaQuery.of(context).size.height - 300,
          child: Column(),
        ),
      ),
      bottomNavigationBar: YourButtonWidget(),
    );
  }

我认为这不是最好的解决方案,但这个变通方案对我很有效。

qeeaahzv

qeeaahzv6#

我也遇到过类似的问题,所以我使用了Scaffold的bottomNavigationBar属性,这就是我的bottomNavigationBar代码的样子。

bottomNavigationBar: Padding(
    padding: const EdgeInsets.all(16.0),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        ElevatedButton(
          onPressed: () {},
          child: const Text("Skip"),
        ),
        ElevatedButton(
          onPressed: () {},
          child: const Text("Next"),
        ),
      ],
    ),
  ),
laik7k3q

laik7k3q7#

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

相关问题