Search code examples
listviewflutterdartflutter-layout

How to show a widget along a ListView on the same screen in Flutter?


I'm trying to build a very simple ToDo app. It consists of a TextField and a Button (a form) on the top of the screen that allow the user to add items to the ListView that is just under the TextField.

I'm capable to display the TextField and the Button, and I'm also capable to display a ListView, but when I try to display both at the same time, the screen is empty.

Am I missing something? I try to display the ListView into a Column widget but it looks like it doesn't work.

Here is my short code without the form:

import 'package:flutter/material.dart';

void main(){
  runApp(MyApp());
}

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return MaterialApp(
      title: "Mon app",
      home: Scaffold(
        appBar: AppBar(
          title: Text("My app")
        ),
        body: Column(
          children: <Widget>[
            ListView(
          children: <Widget>[
            ListTile(
              leading: Icon(Icons.map),
              title: Text('Map'),
            ),
            ListTile(
              leading: Icon(Icons.photo_album),
              title: Text('Album'),
            ),
            ListTile(
              leading: Icon(Icons.phone),
              title: Text('Phone'),
            ),
          ],
        )
          ])),
      );
  }
}

Thanks!


Solution

    1. Wrap your ListView in a column (you already did)

    2. Use mainAxisSize: MainAxisSize.max on the Column

    3. Use an Expanded widget around your ListView** - What is does is to expand its child (in this case, the ListView) to fit the maximum available space on the parent, excluding the space taken by other widgets.

    4. Add the input/widget inside the column's children after the ListView, so the list will scroll and the TextField will always stay on the bottom of the page.

    Here's the code with the bottom input ready, but I suggest you try to understand carefully what's going on with Columns, Rows and Expanded widgets.

    import 'package:flutter/material.dart';
    
    void main(){
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget{
      @override
      Widget build(BuildContext context){
        return MaterialApp(
          title: "Mon app",
          home: Scaffold(
              appBar: AppBar(
                  title: Text("My app")
              ),
              body: Column(
                mainAxisSize: MainAxisSize.max,
                  children: [
                    Expanded(
                      child: ListView(
                        children: [
                          ListTile(
                            leading: Icon(Icons.map),
                            title: Text('Map'),
                          ),
                          ListTile(
                            leading: Icon(Icons.photo_album),
                            title: Text('Album'),
                          ),
                          ListTile(
                            leading: Icon(Icons.phone),
                            title: Text('Phone'),
                          ),
                        ],
                      ),
                    ),
                    Row(
                      children: [
                        Expanded(
                          child: TextField(
                            decoration: InputDecoration(
                              hintText: "What to do?"
                            ),
                          ),
                        ),
                        IconButton(
                          icon: Icon(Icons.send),
                          onPressed: (){
                            //do something
                          },
                        )
                      ],
                    )
                  ],
              ),
          ),
        );
      }
    }