【问题标题】:How to fix a button at bottom of a single child scrollview with a list如何使用列表修复单个子滚动视图底部的按钮
【发布时间】:2021-05-05 18:12:17
【问题描述】:

我有一个 SingleChildScrollView,里面有一个包含一些卡片的列表,您可以删除或添加更多内容。我需要在屏幕底部修复一个添加按钮,当卡片列表还不能滚动,但是当卡片列表增加大小并且滚动视图现在可以滚动(查看所有内容)时,按钮必须跟随列表,不再固定在底部。

现在,我解决这个问题的方法是,每次添加或删除卡片时检查滚动视图,如果我检查屏幕现在可滚动或不可滚动,我会更改构建小部件的一些属性:

 SingleChildScrollView(
          controller: _scrollController,
          physics: AlwaysScrollableScrollPhysics(),
          child: Container(
            height: isNotScrollable
                ? _pageSize - (_appBarSize + _notifySize)
                : null,
            padding: const EdgeInsets.symmetric(
                horizontal: Constraints.paddingNormal),
            child: Column(
.....

在列表渲染之后,我创建了这样的按钮

isNotScrollable
                    ? Expanded(
                        child: Container(),
                      )
                    : Container(),
                CVButton(
                  color: Palette.white,

基本上,我的想法是:如果屏幕还不能滚动(列表内容适合屏幕大小),我将为滚动视图内的容器设置一个高度,并在添加按钮之前添加一个 Expanded() 小部件(因此按钮将留在容器的底部),但是如果屏幕是可滚动的(列表内容不适合屏幕大小),所以我删除了容器高度和 Expanded 小部件,那么按钮现在将像往常一样跟随列表。

我不知道这是否是更好的处理方法,我想知道是否有某种方法可以在没有我正在做的这种“动态”方式的情况下做到这一点,只使用固定的小部件而不改变小部件根据滚动视图的状态。

An example when the list becomes scrollable and the button will keep at list bottom

Here the list is not scrollable yet but the button must be at the screen bottom and not list bottom

(我不想使用底部导航栏)

有人知道我该如何解决这个问题吗?

【问题讨论】:

  • 我不知道该怎么做,但slivers 可能会更容易

标签: flutter dart flutter-layout


【解决方案1】:

我有一个解决方案。检查下面的代码。我添加了一些按钮来添加或删除卡片。主要技巧是使用像 minHeight 这样的约束。

import 'package:flutter/material.dart';

class BottomButton extends StatefulWidget {
  @override
  _BottomButtonState createState() => _BottomButtonState();
}

class _BottomButtonState extends State<BottomButton> {
  List<Widget> cards = [];
  @override
  Widget build(BuildContext context) {
    var appBar2 = AppBar(
      actions: [
        IconButton(
            icon: Icon(Icons.add),
            onPressed: () {
              _addCard();
            }),
        IconButton(
            icon: Icon(Icons.remove),
            onPressed: () {
              _removeCard();
            }),
      ],
    );
    return Scaffold(
      appBar: appBar2,
      body: Container(
        height: MediaQuery.of(context).size.height -
            (MediaQuery.of(context).padding.top + appBar2.preferredSize.height),
        alignment: Alignment.topCenter,
        child: ListView(
          primary: true,
          children: [
            Container(
              constraints: BoxConstraints(
                minHeight: MediaQuery.of(context).size.height -
                    (MediaQuery.of(context).padding.top +
                        appBar2.preferredSize.height),
              ),
              alignment: Alignment.topCenter,
              child: Column(
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Container(
                    constraints: BoxConstraints(
                      minHeight: MediaQuery.of(context).size.height -
                          (MediaQuery.of(context).padding.top +
                              appBar2.preferredSize.height +
                              50),
                    ),
                    alignment: Alignment.topCenter,
                    child: Column(
                      mainAxisSize: MainAxisSize.max,
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: cards,
                    ),
                  ),
                  ElevatedButton(
                    child: Text('this is a button'),
                    onPressed: () {},
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }

  void _addCard() {
    Widget card = Card(
      child: Container(
        height: 100,
        color: Colors.red,
        padding: EdgeInsets.all(2),
      ),
    );
    setState(() {
      cards.add(card);
    });
  }

  void _removeCard() {
    setState(() {
      cards.removeLast();
    });
  }
}

【讨论】:

  • 你能解释一下 minHeight 中的“+ 50”是什么意思吗?它是一个随机数,你在上下文中有意义吗?我现在正在尝试您的建议,对我来说工作 + 100 而不是 + 50。我不知道这是否与手机屏幕尺寸有关,因为我需要的是通用的东西,无论屏幕尺寸如何。但到目前为止,这个建议正在奏效
  • 我对您的代码进行了一些更改,就我的上下文而言,除非我上面所做的“+ 50”问题有问题,否则我认为现在效果更好
  • 50是按钮的高度,它只是一个使按钮停留在页面中的常数。这不是一件好事。如果你可以让它在没有任何常数的情况下工作,那么它在所有屏幕尺寸上都会看起来不错。看起来你已经成功了,很好:)。
猜你喜欢
  • 2014-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多