Flutter Listview: Simple guide for the Android or iOS development

In this article we will give you simple guide as well as examples of the common use cases for making Flutter Listview, specifically Android and iOS listview. Consider this page a reference, bookmark it and come back here to copy-and-paste the code snippets as starters in your own projects.

Firstly, we will look at the basic types of ListViews that are available. After that, we show you how to style the items. Finally, we’ll cover how to make changes by adding and removing items in the list. In addition, we use Android Studio with Flutter 1.0 for this article

Source: pusher.com

Basic types of Flutter ListView

Static ListView

If you have a short list of items which don’t change, you can use the default ListView constructor to make it. This is useful for making something like a settings menu page.

Replace _myListView() with the following:

    Widget _myListView(BuildContext context) {
      return ListView(
        children: <Widget>[
          ListTile(
            title: Text('Sun'),
          ),
          ListTile(
            title: Text('Moon'),
          ),
          ListTile(
            title: Text('Star'),
          ),
        ],
      );
    }

Run the app and you should see the following image. After this when refreshing, usually hot reload works fine, but we find at times we need to do a hot restart or even completely stop and restart the app.

listview

Look back at the code. The children of the Anrdroid & iOS ListView were ListTiles. A ListTile is a special widget that is preconfigured to handle the most common layouts that you would want in a ListView. Our list above only included a title, but a ListTile can also include subtitles, icons, and images. We will come back to ListTiles when we look at styling below.

If you want to add dividers between the rows then use the ListTile.divideTiles constructor.

    Widget _myListView(BuildContext context) {
      return ListView(
        children: ListTile.divideTiles(
          context: context,
          tiles: [
            ListTile(
              title: Text('Sun'),
            ),
            ListTile(
              title: Text('Moon'),
            ),
            ListTile(
              title: Text('Star'),
            ),
          ],
        ).toList(),
      );
    }

The lines are faint, but look carefully:

AHGT

Dynamic Flutter Android & iOS ListView

All of the elements of a static ListView get created at once. This is fine for a short list but not for a long list. You can make a dynamically created ListView by using the ListView.builder() constructor. This will create the ListView items only when they need to be displayed on the screen. It also works like an Android RecyclerView but is a lot easier to set up.

Replace _myListView() with the following:

    Widget _myListView(BuildContext context) {

      // backing data
      final europeanCountries = ['Albania', 'Andorra', 'Armenia', 'Austria', 
        'Azerbaijan', 'Belarus', 'Belgium', 'Bosnia and Herzegovina', 'Bulgaria',
        'Croatia', 'Cyprus', 'Czech Republic', 'Denmark', 'Estonia', 'Finland',
        'France', 'Georgia', 'Germany', 'Greece', 'Hungary', 'Iceland', 'Ireland',
        'Italy', 'Kazakhstan', 'Kosovo', 'Latvia', 'Liechtenstein', 'Lithuania',
        'Luxembourg', 'Macedonia', 'Malta', 'Moldova', 'Monaco', 'Montenegro',
        'Netherlands', 'Norway', 'Poland', 'Portugal', 'Romania', 'Russia',
        'San Marino', 'Serbia', 'Slovakia', 'Slovenia', 'Spain', 'Sweden', 
        'Switzerland', 'Turkey', 'Ukraine', 'United Kingdom', 'Vatican City'];

      return ListView.builder(
        itemCount: europeanCountries.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(europeanCountries[index]),
          );
        },
      );

    }

Which gives:

Flutter listview: Simple guide for the Android or iOS development

Look back at the code. We provided an itemCount that tells the iOs ListView how many list items there will be. We also provided an itemBuilder function that dynamically builds each ListTile as it comes into view. Moreover, the function provides the BuildContext as the context parameter and the item position as the index parameter. The index makes it convenient to get the data items from the list of European country names that we are using as the backing data.

Infinite list – ios listview

Flutter makes it simple, though. Just remove the itemCount parameter from the ListView.builder constructor. Since Europe doesn’t have an infinite number of countries, we’ll change the ListTile to display the row index.

Replace _myListView() with the following:

    Widget _myListView(BuildContext context) {
      return ListView.builder(
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('row $index'),
          );
        },
      );
    }

Which gives:

guide

Then, you can scroll all day and you’ll never get to the end. That was way too easy.

Moreover, if you want to add dividers between tiles in a dynamic ListView, you can use the ListView.separated constructor.

    Widget _myListView(BuildContext context) {
      return ListView.separated(
        itemCount: 1000,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('row $index'),
          );
        },
        separatorBuilder: (context, index) {
          return Divider();
        },
      );
    }
Flutter listview: Simple guide for the Android or iOS development

Again, you have to look carefully to see the dividers. You can add arguments to Divider() if you want to change the line height or color.

Horizontal ListView – ios listview

It’s also really easy to make a horizontally scrolling ios ListView. All you have to do is specify the scrollDirection as horizontal. Since ListTiles aren’t designed for horizontal ListViews, we will use a simple custom layout.

Replace _myListView() with the following:

    Widget _myListView(BuildContext context) {
      return ListView.builder(
        scrollDirection: Axis.horizontal,
        itemBuilder: (context, index) {
          return Container(
            margin: const EdgeInsets.symmetric(horizontal: 1.0),
            color: Colors.tealAccent,
            child: Text('$index'),
          );
        },
      );
    }

Which gives:

Flutter listview: Simple guide for the Android or iOS development

Styling

We’ve covered the main ListView types above, but they were pretty plain. Flutter offers a lot of options to make them more beautiful.

ListTile customization – ios listview

The Flutter team designed the ListTile widget to handle the normal content that you would want in a list. This means that most of the time there is no need to define a custom layout. You can just use the default ListTile for each item in the list. When we made a ListView in the example above we only used the title option. But we can also show subtitles, images, and icons.

Replace _myListView() with the following:

    Widget _myListView(BuildContext context) {
      return ListView(
        children: <Widget>[
          ListTile(
            leading: Icon(Icons.wb_sunny),
            title: Text('Sun'),
          ),
          ListTile(
            leading: Icon(Icons.brightness_3),
            title: Text('Moon'),
          ),
          ListTile(
            leading: Icon(Icons.star),
            title: Text('Star'),
          ),
        ],
      );
    }

The leading is for adding an icon or image at the start of the ListTile.

trailing

You can also add an icon at the end if you specify the trailing attribute.

    ListTile(
      leading: Icon(Icons.wb_sunny),
      title: Text('Sun'),
      trailing: Icon(Icons.keyboard_arrow_right),
    ),
hint

The right arrow icon makes it look like the list items are clickable, but they aren’t. Not yet. We will see how to add touch events in the next section. It’s easy. (Hint: onTap )

Instead of icons, we can also use images. The recommended image option is to use a CircleAvatar widget.

Replace _myListView() with the following:

    Widget _myListView(BuildContext context) {
      return ListView(
        children: <Widget>[
          ListTile(
            leading: CircleAvatar(
              backgroundImage: AssetImage('assets/sun.jpg'),
            ),
            title: Text('Sun'),
          ),
          ListTile(
            leading: CircleAvatar(
              backgroundImage: AssetImage('assets/moon.jpg'),
            ),
            title: Text('Moon'),
          ),
          ListTile(
            leading: CircleAvatar(
              backgroundImage: AssetImage('assets/stars.jpg'),
            ),
            title: Text('Star'),
          ),
        ],
      );
    }

It won’t work yet because we need to add the images.

You could have used NetworkImage(imageUrl) instead of AssetImage(path). I chose AssetImage, though, so that everything is self-contained here. Create an assets folder in the project’s root directory and add the following images to it:

ig1
img2
img3

In pubspec.yaml register the assets location:

    flutter:
      assets:
        - assets/

Do a full restart (stop and start) of the app. This gives us the following:

Flutter listview styling

Before we leave ListTile customization, one last thing we should cover is subtitles. Edit the code above to add a subtitle argument.

    ListTile(
      leading: CircleAvatar(
        backgroundImage: AssetImage('assets/sun.jpg'),
      ),
      title: Text('Sun'),
      subtitle: Text('93 million miles away'), //           <-- subtitle
    ),
Flutter listview: Simple guide for the Android or iOS development

As you can see, the subtitle adds a line of smaller text below the title.

Custom list item

If a ListTile doesn’t fit your needs, you are free to design your own tile. Remember, all that Android & iOS ListView wants is a list of widgets. Any widget is fine. Here is a simplified example.

    Widget _myListView(BuildContext context) {

      // the Expanded widget lets the columns share the space
      Widget column = Expanded(
        child: Column(
          // align the text to the left instead of centered
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text('Title', style: TextStyle(fontSize: 16),),
            Text('subtitle'),
          ],
        ),
      );

      return ListView.builder(
        itemBuilder: (context, index) {
          return Card(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                children: <Widget>[
                  column,
                  column,
                ],
              ),
            ),
          );
        },
      );

    }
Flutter listview

Updating list data

Adding and deleting rows in a ListView

It is pretty easy to update the items in a normal iOS ListView. All you have to do is use a Stateful widget and call setState() whenever the row data changes.

Since we need a Stateful widget, replace both BodyLayout and _myListView() with the following code:

    class BodyLayout extends StatefulWidget {
      @override
      BodyLayoutState createState() {
        return new BodyLayoutState();
      }
    }

    class BodyLayoutState extends State<BodyLayout> {

      List<String> titles = ['Sun', 'Moon', 'Star'];

      @override
      Widget build(BuildContext context) {
        return _myListView();
      }

      Widget _myListView() {
        return ListView.builder(
          itemCount: titles.length,
          itemBuilder: (context, index) {
            final item = titles[index];
            return Card(
              child: ListTile(
                title: Text(item),

                onTap: () { //                                  <-- onTap
                  setState(() {
                    titles.insert(index, 'Planet');
                  });
                },

                onLongPress: () { //                            <-- onLongPress
                  setState(() {
                    titles.removeAt(index);
                  });
                },

              ),
            );
          },
        );
      }
    }

When you tap an item it adds a “Planet” item at that index. When you long press an item, it removes it.

Flutter listview

The problem with this method, though, is that the changes are abrupt. To make adding and deleting rows look nicer, Flutter has an AnimatedList widget.

Adding and deleting rows in an AnimatedList – Android and ios listview

Replace the BodyLayoutState class with the following code:

    class BodyLayoutState extends State<BodyLayout> {

      // The GlobalKey keeps track of the visible state of the list items
      // while they are being animated.
      final GlobalKey<AnimatedListState> _listKey = GlobalKey();

      // backing data
      List<String> _data = ['Sun', 'Moon', 'Star'];

      @override
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            SizedBox(
              height: 300,
              child: AnimatedList(
                // Give the Animated list the global key
                key: _listKey,
                initialItemCount: _data.length,
                // Similar to ListView itemBuilder, but AnimatedList has
                // an additional animation parameter.
                itemBuilder: (context, index, animation) {
                  // Breaking the row widget out as a method so that we can
                  // share it with the _removeSingleItem() method.
                  return _buildItem(_data[index], animation);
                },
              ),
            ),
            RaisedButton(
              child: Text('Insert item', style: TextStyle(fontSize: 20)),
              onPressed: () {
                _insertSingleItem();
              },
            ),
            RaisedButton(
              child: Text('Remove item', style: TextStyle(fontSize: 20)),
              onPressed: () {
                _removeSingleItem();
              },
            )
          ],
        );
      }

      // This is the animated row with the Card.
      Widget _buildItem(String item, Animation animation) {
        return SizeTransition(
          sizeFactor: animation,
          child: Card(
            child: ListTile(
              title: Text(
                item,
                style: TextStyle(fontSize: 20),
              ),
            ),
          ),
        );
      }

      void _insertSingleItem() {
        String newItem = "Planet";
        // Arbitrary location for demonstration purposes
        int insertIndex = 2;
        // Add the item to the data list.
        _data.insert(insertIndex, newItem);
        // Add the item visually to the AnimatedList.
        _listKey.currentState.insertItem(insertIndex);
      }

      void _removeSingleItem() {
        int removeIndex = 2;
        // Remove item from data list but keep copy to give to the animation.
        String removedItem = _data.removeAt(removeIndex);
        // This builder is just for showing the row while it is still
        // animating away. The item is already gone from the data list.
        AnimatedListRemovedItemBuilder builder = (context, animation) {
          return _buildItem(removedItem, animation);
        };
        // Remove the item visually from the AnimatedList.
        _listKey.currentState.removeItem(removeIndex, builder);
      }
    }

This is the result:

Flutter listview: Simple guide for the Android or iOS development

Conclusion

We have taken a tour of Android and iOS ListView. You should have a solid understanding now of how to implement the vast majority of use cases that you will encounter. The source code for this tutorial is available on GitHub.

Most important, we see the future of Flutter in bright colors. Just be aware that the framework still has some issues. However, they are mostly related to the immaturity of the technology and are likely to become less cumbersome in the future.

Above all, we – ArrowHiTech is proud to be one of the most famous outsourcing companies all around the world. With over 14 years of experience, we can provide the Flutter development services for your business. Our Flutter cross-platform app development services combine our state-of the-art solutions with the Flutter qualities such as speedy development, expressive UI, native performance, amazing visuals and cost-effectiveness to ensure you get the best app in less time and cost.

Tags

Share