I’m currently using flutter web to build a simple website, i’m trying to make a footer at the bottom of the screen.
My main problem is : i don’t want a fixed footer i want it to be at the end of the ScrollView but with a sticky header.
You can check attached screenshots to see what is my problem and what i want 🙂
Please don’t answer only code i really want to understand how to layout work in flutter and why it’s not working with spacer inside my widget 🙂
Regards, RaYmMiE
This is my code, i sometime use Spacer(), but it’s not working here and i’m trying to figure out why :/
import 'package:flutter/material.dart';
class Test extends StatefulWidget {
static const String route = '/test';
const Test({super.key});
@override
State<Test> createState() => _TestState();
}
class _TestState extends State<Test> {
@override
Widget build(BuildContext context) {
return
Scaffold(
backgroundColor: Colors.white,
body: Column(
mainAxisSize: MainAxisSize.max,
children: [
SingleChildScrollView(
child: Column(children: [
Container(height: 200, width: double.infinity, color: Colors.blueAccent,),
Container(height: 200, width: double.infinity, color: Colors.redAccent,),
//Spacer(),
Container(height: 200, width: double.infinity, color: Colors.yellowAccent,),
Align(alignment: Alignment.bottomCenter, child: Container(height: 200, width: double.infinity, color: Colors.greenAccent,),)
]),
)]
),
);
}
}
2
Answers
Your Spacer is not working because Columns, or scroll viewports always give unbound constraints in the scroll direction (or infinite space).
Per default a column will size itself to the maximum of the incoming constraints in the main axis (or scroll diration), except if it has MainaxisSize.min, or receives unbound constraints iutself. Then it will size itself to the sum of the children.
Now the problem is a Spacer (like any Flex widget) tries to size itself to fill a portion of the available/free space which works fine if the column itself can expand. But if the column has to shrink in size to fit the children, then how could the spacer fill a portion of what available space?
Also if we look at scrollable viewports, they available space for the children is always infinite (or the unbound constraints) in the scroll direction (or main axis), because well, they can scroll. So you can’t really use flexible widgets inside of a scrollable viewport.
So if we want to combine scrolling if the widgets are too big for the screen, but also have something that fills a portion of the available space if the widgets are smaller than the screen size, then you can use the following:
Here you have no scrolling but flexible space at first, but then when the buttons get too big, you will have scrolling and no flexible space.
But the layout algorithm will be twice as expensive (performance wise) for this example!
Coming back to your initial code snippet, if you want to use a Spacer, you have to remove the scroll view and also "expand" the inner column, so that it takes up the remaining space of the outer column instead of receiving unbound constraints:
The issue in your current code is that you wrapped your Column inside a SingleChildScrollView. This means that the height of your Column is not limited by the screen height but can be as large as necessary to display all the children of the column. So even if you add a Spacer() at the end of the column, it won’t push the last child down because the column can continue to expand.
So, if we want to combine scrolling if the widgets are too large for the screen but also have something that fills some of the available space if the widgets are smaller than the screen size, then you can use the following approach:
SliverFillRemaining is a sliver that contains a single box child that fills the remaining space in the viewport.
I discuss this in one of my blog posts.