I'm trying to build a layout where there are two Text objects at the top and bottom which stays stationery and a ListView at their center.
Here's the code for the Screen
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 40.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(vertical: 40.0),
child: Text(
DateFormat("hh:mm 'PM ,' MMMM d").format(DateTime.now()),
style: Theme.of(context).textTheme.title,
),
),
Expanded(
child: ListView.builder(
itemCount: 4,
itemBuilder: (BuildContext context, int index) =>
CustomAppText(
text: 'Custom App',
),
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 40.0),
child: Text(
"Settings",
style: Theme.of(context).textTheme.title,
),
),
],
),
),
),
);
}
}
The output of the given code
The Design I'm looking for
I have tried using the Center widget but it does not center the ListView
You can wrap your ListView widget inside the Expanded widget and this will allow the ListView to take all the available as long as the Column allows.
A Column widget is flexible - it will try to take up as much space as it needs but no more. If you want it to take up all availible space, then wrap it in an Expanded widget. This only works if the Column is inside another Flex widget, as Expanded can only be placed inside a Flex widget.
The solution is to place a Container as the only children in the ListView , and give it a minimum height equal to the available space for the height (Use LayoutBuilder to measure the maximum height for the widget). Then as the Container 's child, you can either place a Center or Column (with MainAxisAlignment.
The ListView fills the entire Expanded Widget, that's why using the Center widget didn't work, so shrinkWrap: true
should be added so the ListView takes only the height of it's children.
After skimming through the documentation I found about Flexible Widget
Flexible, which does not force the child to fill the available space.
Made the change and works like a charm
Flexible(
child: ListView.builder(
shrinkWrap: true,
itemCount: 4,
itemBuilder: (BuildContext context, int index) =>
CustomAppText(
text: 'Custom App',
),
),
),
For those still looking for an answer, this is what worked for me:
Column(
children: [
Container(), // some top content
Expanded(
child: Center(
child: ListView(
shrinkWrap: true,
children: [] //your list view content here
)
)
),
Container(), // some bottom content
]
)
The Expanded widget makes the content take up all available space.
The Center widget centers the content you want to display.
The ListView holds your list content and the "shrinkWrap: true" property makes your list view shrink according to content size(allowing it to centralized by the Center widget when it's not taking a lot of space).
Hope it helps. Give the top and bottom widgets the 25% of the screen size. Give the listview the 50% of the screen size.
import 'package:flutter/material.dart';
class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
@override
Widget build(BuildContext context) {
final _size = MediaQuery.of(context).size;
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(28.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// Top Widgets
Container(
width: double.infinity,
// color: Colors.green,
height: _size.height * 0.25, // Take 25% width of the screen height
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('11: 25 AM', style: TextStyle(fontSize: 23.0),),
Text('Set As Launcher', style: TextStyle(fontSize: 23.0),)
],
),
),
Expanded(
child: Container(
// color: Colors.yellow,
child: ListView(
children: List.generate(25, (index){
return Text('Custom App $index', style: TextStyle(fontSize: 45.0),);
}),
),
),
),
// Bottom Widgets
Container(
width: double.infinity,
// color: Colors.blue,
height: _size.height * 0.25, // Take 25% width of the screen height
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Settings', style: TextStyle(fontSize: 23.0),),
],
),
)
],
),
),
),
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With