当孩子的尺寸小于屏幕尺寸时,使用 Stack 非常容易控制布局。但是当孩子的身高大于屏幕尺寸时,就需要使用SingleChildScrollView
。但是如果我使用它,整个屏幕会变白并产生如下所示的错误。
在这些情况下使用 Stack
和 SingleChildScrollView
时如何处理布局。
任何帮助是极大的赞赏。谢谢。
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
════════════════════════════════════════════════════════════════════════════════
答案 0 :(得分:2)
原因:
SingleChildScrollView 提供无限空间。
堆栈自身大小以包含所有未定位的子项,这些子项根据对齐方式定位(默认为从左到右环境中的左上角和从右到左环境中的右上角环境)。然后根据它们的顶部、右侧、底部和左侧属性相对于堆栈放置已定位的子项。
小部件永远膨胀。
它也会导致 StackRender 算法出现问题,因为它会处理 Zenith。
Read more in the api documentation here.
解决方案给它一个约束,比如一个 SizedBox();
答案 1 :(得分:1)
用容器包裹您的堆栈并使用 MediaQuery 定义其高度和宽度,然后用一列包裹容器。
答案 2 :(得分:1)
首先整个屏幕变白,因为 StackFit.expand
告诉堆栈尽可能地扩展,并且因为它在 SingleChildScrollView
内是无穷大并且无法处理。
第二个是堆栈高度是根据它的孩子定义的,而不计算位置小部件的高度,比如css position:absolute;
,如果你熟悉的话,剩下的就是你的_Background
whcih定义堆栈高度的小部件..
所以现在 SingleChildScrollView 和它的孩子有(屏幕高度)高度 = 没有滚动,为了解决这个问题,我们必须指定足够的高度,让我们定位的小部件出现在我们的堆栈中,以便我们的堆栈能够滚动进来。
如何修复
第一个在您的堆栈中将适合更改为
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,
);
}
}