【问题标题】:Handling stack when the size of the children exceeds screen size当子项的大小超过屏幕大小时处理堆栈
【发布时间】:2021-07-18 03:21:49
【问题描述】:

当孩子的尺寸小于屏幕尺寸时,使用 Stack 很容易控制布局。但是当孩子的身高大于屏幕尺寸时,就需要使用SingleChildScrollView。但是如果我使用它,整个屏幕会变白并产生如下所示的错误。

在这些情况下使用StackSingleChildScrollView 时如何处理布局。 任何帮助是极大的赞赏。谢谢。

示例代码

import 'package:flutter/material.dart';

void main(List<String> args) {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          child: SingleChildScrollView(
            child: Stack(
              fit: StackFit.expand,
              children: [
                _Background(),
                Positioned(left: 0, top: 100, child: WidgetA()),
                Positioned(left: 0, top: 270, child: WidgetB()),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _Background extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      height: MediaQuery.of(context).size.height,
      width: MediaQuery.of(context).size.width,
    );
  }
}

class WidgetA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: randomHeight(),
      width: MediaQuery.of(context).size.width,
      color: Colors.purple,
      child: Center(
        child: Text('Widget A'),
      ),
    );
  }
}

class WidgetB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 250,
      width: MediaQuery.of(context).size.width,
      color: Colors.yellow,
      child: Center(
        child: Text('Widget B'),
      ),
    );
  }
}

错误

════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderRepaintBoundary#2e73f relayoutBoundary=up1 NEEDS-PAINT
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1940 pos 12: 'hasSize'

The relevant error-causing widget was
Scaffold
lib/main.dart:11
════════════════════════════════════════════════════════════════════════════════

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案1】:

    原因:

    SingleChildScrollView 提供无限空间。

    堆栈本身的大小以包含所有未定位的子项,这些子项根据对齐方式进行定位(在从左到右的环境中默认为左上角,在从右到左的环境中默认为右上角环境)。然后根据它们的 top、right、bottom 和 left 属性相对于堆栈放置定位的子项。

    小部件永远膨胀。

    它还会导致 StackRender 算法出现问题,因为它会处理 Zenith。

    Read more in the api documentation here.

    解决方案给它一个约束,例如 SizedBox();

    【讨论】:

      【解决方案2】:

      用一个容器包裹你的堆栈并用 MediaQuery 定义它的高度和宽度,然后用一个列包裹容器。

      【讨论】:

      • 感谢您的回答。我会尝试看看会发生什么。
      • 它的错误! ``` RenderBox 未布置:RenderFlex#5f5fc relayoutBoundary=up2 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE 'package:flutter/src/rendering/box.dart':断言失败:第 1940 行 pos 12:'hasSize' ```
      【解决方案3】:

      首先整个屏幕变白,因为StackFit.expand 告诉堆栈尽可能地扩展,并且因为它在SingleChildScrollView 内部,所以它是无穷大的,无法处理。

      第二个是堆栈高度是根据其子级定义的,并且不计算 Position 小部件高度,如 css position:absolute; 如果您熟悉它,那么剩下的是您的 _Background 这是定义的小部件堆栈的高度..

      所以现在 SingleChildScrollView 及其子项具有(屏幕高度)高度 = 无滚动,为了解决这个问题,我们必须指定足够的高度,以便我们定位的小部件出现在其中,并且我们的堆栈能够滚动进去。

      如何解决

      first 在您的堆栈中将 fit 更改为

       child: Stack(
                  fit: StackFit.loose,
      

      第二个你的背景,上面提到的负责高度

      class _Background extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return Container(
            color: Colors.red,
            height: MediaQuery.of(context).size.height + 250, // <-- change this
            width: MediaQuery.of(context).size.width,
          );
        }
      }
      

      【讨论】:

      • 亲爱的朋友,感谢您的回答。我已经尝试了所有这些。 loose 没有任何作用。我为_Background 添加了额外的尺寸,希望它能够正确安装。当总屏幕尺寸小于屏幕尺寸时,这一切都可以完美运行。
      • 你是不是变松了并且改变了_Background的高度?
      • 是的,正如我所说,改变背景的高度使其适合屏幕。但这就是我的问题。我想让堆栈中的小部件比屏幕高度长。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-05
      • 2020-08-10
      • 1970-01-01
      • 1970-01-01
      • 2013-12-13
      • 2017-02-04
      • 2014-08-19
      相关资源
      最近更新 更多