Starting With Flutter: Lists

Are you willing to start developing in Flutter but you don’t even know how to set up a list of elements? Well fear not! I’ve come to show you how to create a simple list of items in Flutter. For free!!!

I imagine you’re already familiar with Flutter, Dart and declarative programming, if not, you should go through these tutorials first.

We’ll be focusing on creating a custom list with an array of custom items, because it may be the most common situation to address with list. Also we won’t see scaffolds creation or any other starting point.

1. Create data structure

First things first, let’s create a data structure and a list of objects. I think that a simple “newsfeed” data will be enough for our example:

class News {
  int id;
  String title, content, image_url, link;

  News(this.id, this.title, this.content, this.image_url, this.link);
}

Simple as that. A unique id, title, content, image and a link to a webpage.

Then we’ll create a simple list of those objects:

List<News> lNews = List();
lNews.add(News(1, "Title1", LoremIpsumTEXT, "https://www.at-languagesolutions.com/wp-content/uploads/2016/06/http-1-1024x824.jpg", "https://www.google.com/"));
lNews.add(News(2, "Title2", "Lorem Ipsum2", "https://media.wired.com/photos/5b8999943667562d3024c321/master/w_2560%2Cc_limit/trash2-01.jpg", "https://www.google.com/"));
lNews.add(News(3, "Title3", "Lorem Ipsum3", "https://upload.wikimedia.org/wikipedia/commons/4/4b/What_Is_URL.jpg", "https://www.google.com/"));

Possibly those items would be the payload of a API call.

2. Build the list element

In spite of what you may think you can use any widget as list item so, because ListTile is not really what we want, we can create a new Stateless widget and call it ListElem.

We wish to add the image to the left, on the right the title in bold and 2 lines max of content, so we can create the Stateless Widget that represents it. We also need to add a News item as component for the constructor because the widget needs to know which data render.

class ListElem extends StatelessWidget {
  final News news;

  const ListElem({Key key, this.news}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        children: [
          //The image
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Container(
              width: 80,
              height: 80,
              decoration: BoxDecoration(
                  image: DecorationImage(
                      fit: BoxFit.cover,
                      alignment: FractionalOffset.topCenter,
                      image: NetworkImage(news.image_url))),
            ),
          ),
          Expanded(
            child: Padding(
              padding: const EdgeInsets.only(right: 8.0),
              child: Container(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  mainAxisSize: MainAxisSize.max,
                  children: [
                    //The title
                    Text(
                      news.title,
                      textAlign: TextAlign.left,
                      style: TextStyle(
                        fontSize: 14,
                        fontWeight: FontWeight.bold
                      ),
                    ),
                    //The content
                    Text(
                      news.content,
                      maxLines: 2,
                      textAlign: TextAlign.left,
                      overflow: TextOverflow.ellipsis,
                      style: TextStyle(
                          fontSize: 12,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          )
        ],
      ),
    );
  }
}

3. Add the list to our body

We pretty much have all out elements in order, then we just need to create a list. The ListView widget comes with a “children” parameter which takes an array of widgets. So we can create an array of LIstElem and give it to the ListView.

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(
        children: _getListElements(lNews),
      ),
    );
  }

List<Widget> _getListElements(List<News> allNews) {
    List<Widget> widgets = List();
    for (var n in allNews) {
      widgets.add(ListElem(news: n));
    }

    return widgets;
  }

Another way to create a ListView is by using a builder which is a bit more similar on how Android creates lists. You’ll need to know the number of items (e.g. the lenght of the array) and with the itemBuilder all the items will be created by the framework:

return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView.builder(
        itemCount: lNews.length,
        itemBuilder: (BuildContext context, int position) {
          News item = lNews[position];
          return ListElem(news: item);
        },
      ),
    );

This last one is a way cleaner method to generate a list and is the one that I suggest you to use.

Still with both ways we’ll obtain the same result:

There you are. You can customize your list items as you wish because ListView just needs an array of widgets so you can easily create way more complex layouts and also mix different list items.

One Response

Add a Comment

Your email address will not be published. Required fields are marked *