Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Center Expanded ListView inside Column Flutter

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 Output of given code

The Design I'm looking for Desired output

I have tried using the Center widget but it does not center the ListView

like image 493
Aswin Mohan Avatar asked Dec 02 '18 06:12

Aswin Mohan


People also ask

Can I put ListView inside column flutter?

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.

Can we use expanded in column in flutter?

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.

How do I center ListView items in flutter?

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.


3 Answers

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',
    ),
  ),
),
like image 75
Aswin Mohan Avatar answered Sep 20 '22 20:09

Aswin Mohan


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).

like image 37
Gilbert Nwaiwu Avatar answered Sep 23 '22 20:09

Gilbert Nwaiwu


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),),                    
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

enter image description here

like image 30
Sagar Bahadur Tamang Avatar answered Sep 20 '22 20:09

Sagar Bahadur Tamang