Flutter - How to center widget inside list view

Viewed 100414

I'm struggling with centering a widget inside listView.

I tried this, but Text('ABC') is not centered vertically. How can I achieve this?

new Scaffold(
  appBar: new AppBar(),
  body: new ListView(
    padding: const EdgeInsets.all(20.0),
    children: [
      new Center(
        child: new Text('ABC')
      )
    ]
  )
);
9 Answers

Vertically Center & Horizontal Center:

Scaffold(
  appBar: new AppBar(),
  body: Center(
    child: new ListView(
      shrinkWrap: true,
        padding: const EdgeInsets.all(20.0),
        children: [
          Center(child: new Text('ABC'))
        ]
    ),
  ),
);

Only Vertical Center

Scaffold(
  appBar: new AppBar(),
  body: Center(
    child: new ListView(
      shrinkWrap: true,
        padding: const EdgeInsets.all(20.0),
        children: [
          new Text('ABC')
        ]
    ),
  ),
);

Solving this question with shrinkWrap = true is a hack. The whole point of centering widgets inside a ListView is to have bounciness and scrolling enabled. Using shrinkWrap doesn't achieve this, it looks visually correct but it behaves completely wrong.

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.center) widget and from there you can add whatever widgets you intended to center.

Below is the code to solve the example in the question:

Scaffold(
  appBar: AppBar(),
  body: LayoutBuilder(
    builder: (context, constraints) => ListView(
      children: [
        Container(
          padding: const EdgeInsets.all(20.0),
          constraints: BoxConstraints(
            minHeight: constraints.maxHeight,
          ),
          child: Center(
            child: Text('ABC'),
          ),
        )
      ],
    ),
  ),
);

Wrap your widget into container

Container(alignment: Alignment.center, ...)

or

Container(alignment: Alignment.centerLeft, ...)

enter image description here


Simply wrap your widget in Align and provide alignment accordingly.

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView( // your ListView
        children: <Widget>[
          Align(
            alignment: Alignment.centerLeft,
            child: _button("Left"),
          ),
          Align(
            alignment: Alignment.center,
            child: _button("Middle"),
          ),
          Align(
            alignment: Alignment.centerRight,
            child: _button("Right"),
          ),
        ],
      ),
    );
  }

  Widget _button(text) => RaisedButton(onPressed: () {}, child: Text(text));
}

Use Align inside your ListView which will render Widgets at the center, Also we don't have to give any alignment property as by default it is center

This will add ListView at the center of the screen, as the list item increases it will grow from the center only.

   Center(
        child: ListView.builder(
          shrinkWrap: true,
          scrollDirection: Axis.vertical, // Axis.horizontal for horizontal list view.
          itemCount: 2,
          itemBuilder: (ctx, index) {
            return Align(child: Text('Text'));
          },
        ),
      ),

Output:

enter image description here

Just use the Align widget to center a child widget vertically and/or horizontally:

   Align(
    alignment: Alignment.center,
    child: Text(
      'middle',
    ),

Note: if you have a column as a child, you will have to add :

mainAxisAlignment: MainAxisAlignment.center 

to the column to align it vertically.

If you need the item in the center to scroll then do the following.

Center(
  child: ListView(
    shrinkWrap: true,
    children: [
      // the container with height will make the screen scroll
      Container(
        height:
             MediaQuery.of(context).size.height / 1.2,
        child: Text('ABC'),
      ),
    ],
  ),
),

Tip: give the container a color to visualize the areas that can scroll

    Scaffold(
      backgroundColor: Color.fromARGB(255, 238, 237, 237),
      body: Center(
        child: Container(
          child: Column(
            children: <Widget>[
              Column(children: <Widget>[
                Image.asset(
                  'images/logo.png',
                  fit: BoxFit.contain,
                  width: 130,
                )
              ]),
              Column(children: <Widget>[
                RaisedButton(
                  onPressed: () => {},
                  child: TextStyle_Title(
                    text: 'سلاااام',
                  ),
                )
              ]),
            ],
          ),
        ),
      ),
    )

Add this container in your listview

Container(
            height: MediaQuery.of(context).size.height / 1.2,
            child: Center(
              child: Text(
                "No Record Found",
                style: TextStyle(fontSize: 20, color: Colors.black),
              ),
            ),
          ),
Related