简体   繁体   中英

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 给定代码的输出

The Design I'm looking for期望的输出

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

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

在此处输入图片说明

Just add an Expanded as a wrapper for your first Container inside the Column

        Expanded(
                        child: Container(
                          margin: EdgeInsets.symmetric(vertical: 40.0),
                          child: Text(
                            DateFormat("hh:mm 'PM ,'  MMMM d").format(DateTime.now()),
                            style: Theme.of(context).textTheme.title,
                          ),
                        ),
                      ),

Just wrap your ListView.builder inside a container class and give it a height, either explicitly in double or as a percentage of screen height.

class Trial 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(
                  "Some Text",
                  style: Theme.of(context).textTheme.title,
                ),
              ),
              Container(
//                height: 40,
                height: MediaQuery.of(context).size.height * 0.4,
                child: ListView.builder(
                  itemCount: 20,
                  itemBuilder: (BuildContext context, int index) {
                    return Text("Hello");
                  }
                ),
              ),
              Container(
                margin: EdgeInsets.symmetric(vertical: 40.0),
                child: Text(
                  "Settings",
                  style: Theme.of(context).textTheme.title,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Add two spacer it will give you 100% same result as you expected

      Spacer(),
          Expanded(
            child: ListView.builder(
              itemCount: 4,
              itemBuilder: (BuildContext context, int index) =>
                  CustomAppText(
                    text: 'Custom App',
                  ),
            ),
          ),
          Spacer(),

It have to use shrinkWrap: true and Flexible together to show all items of ListView.

Flexible(
        child: ListView.builder(
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          scrollDirection: Axis.vertical,
          itemCount: models.length,

如果你用Container替换你的Expanded小部件并给它一个固定的height ,我想你会得到你想要的。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM