在ListView内部放置具有动态大小内容的堆栈

时间:2019-06-12 23:06:07

标签: flutter dart

我想在ListView内放置一个堆栈。但是,堆栈具有可扩展的卡片(即动态高度),因此我无法将堆栈放置在ConstrainedBox内。

我尝试将Stack放在IntrinsicHeight小部件中,但是所有页面内容都消失了。

这是我的一些代码:

Scaffold(
      body: ListView(
        padding: EdgeInsets.zero,
        children: <Widget>[
          Stack(
            children: <Widget>[
              Positioned(
                top: 0.0,
                left: 0.0,
                right: 0.0,
                child: Image.asset(),
              ),
              Positioned(
                left: _width * 5.55 / 100,
                right: _width * 5.55 / 100,
                top: _height * 25.31 / 100,
                child: ClipPath(
                  clipper: BottomCardClipper(
                    screenWidth: _width,
                    screenHeight: _height,
                  ),
                  child: Card(
                    // This card is expandable
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    );

我得到了这个错误:

I/flutter ( 4412): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 4412): The following assertion was thrown during performLayout():
I/flutter ( 4412): RenderStack object was given an infinite size during layout.
I/flutter ( 4412): This probably means that it is a render object that tries to be as big as possible, but it was put
I/flutter ( 4412): inside another render object that allows its children to pick their own size.

1 个答案:

答案 0 :(得分:0)

我将堆栈放置在ConstrainedBox内,并为其minHeight属性添加了可变高度。我还创建了一个函数来计算堆栈高度。 因此,在呈现页面时或每次Card的高度发生变化时,我都会计算堆栈高度并设置minHeight变量的状态。 以下代码说明了解决方案:

首先,我定义了Stack height变量和一个GlobalKey来获取Card的高度:

double _stackHeight = 0.0;
GlobalKey key = GlobalKey<_BusinessCardState>();

然后,我将堆栈放在ConstrainedBox小部件内,并将密钥分配给Card小部件:

Scaffold(
    body: ListView(
      padding: EdgeInsets.zero,
      children: <Widget>[
        ConstrainedBox(
          constraints: BoxConstraints(minHeight: _stackHeight),
          child: Stack(
            children: <Widget>[
              Positioned(
                top: 0.0,
                left: 0.0,
                right: 0.0,
                child: Image.asset(),
              ),
              Positioned(
                left: _width * 5.55 / 100,
                right: _width * 5.55 / 100,
                top: _height * 25.31 / 100,
                child: ClipPath(
                  clipper: BottomCardClipper(
                    screenWidth: _width,
                    screenHeight: _height,
                  ),
                  child: Card(
                    key: key,
                    ...
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    )
  );

然后,我创建了一个函数,可以使用其键来计算卡片高度:

_getCardHeight() {
    double height = MediaQuery.of(context).size.height;
    final RenderBox renderBoxRed = key.currentContext.findRenderObject();
    return renderBoxRed.size.height;
  }

最后,当页面在initState函数中完成渲染时,我调用了该函数:

@override
  void initState() {
    super.initState();
    if (SchedulerBinding.instance.schedulerPhase ==
        SchedulerPhase.persistentCallbacks) {
      SchedulerBinding.instance.addPostFrameCallback((context) {
        setState(() {
          _stackHeight = _getCardHeight();
        });
      });
    }
  }

我需要设置_stackHeight变量的状态时,可以随时调用_getCardHeight()函数。