Reputation: 2872
It is very easy to control the layout using Stack when the children's size is less than that of the screen. But when the children's height is greater than that of the screen size, you will need to use SingleChildScrollView
. But if I use this, the whole screen goes white and produces the error shown below.
How can I handle the layout when using Stack
& SingleChildScrollView
in these circumstances.
Any help is greatly appreciated. Thank you.
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
════════════════════════════════════════════════════════════════════════════════
Upvotes: 1
Views: 952
Reputation: 1009
Cause:
The SingleChildScrollView Provides Infinite Space.
The stack sizes itself to contain all the non-positioned children, which are positioned according to alignment (which defaults to the top-left corner in left-to-right environments and the top-right corner in right-to-left environments). The positioned children are then placed relative to the stack according to their top, right, bottom, and left properties.
The widget inflates forever.
It will also cause problems with the StackRender Algorithm as that will deal with the Zenith.
Read more in the api documentation here.
Solution give it a Constraint such as a SizedBox();
Upvotes: 2
Reputation: 1744
first the whole screen goes white because the StackFit.expand
tell the stack to expand as much as possible and since it is inside SingleChildScrollView
that is infinity and can't be handled.
second is that the stack height is defined based on its children and the Position widget height is not calculated , like css position:absolute;
if you are familiar with that , so the remaining is your _Background
whcih is the widget that define the height of the stack ..
so now SingleChildScrollView and its child has (screen height) height = no scrolling and to solve this we have to specify height enough for our positioned widgets to appear in and for our stack to be able to scroll in.
How to fix
first in your stack change fit to
child: Stack(
fit: StackFit.loose,
second your background which is responsible for the height as mentioned above
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,
);
}
}
Upvotes: 1
Reputation: 46
Wrap your stack with a container and define it's height and width with MediaQuery, then wrap the container with a column.
Upvotes: 1