Skip to content

[Flutter] Use "ListView" to create a list component

Last Updated on 2021-03-25 by Clay


Introduction

If you have the need to create a long "list" in Flutter, you can use the "ListView" component to do it.

It looks like this:

Today, I want to record following several different methods to use ListView.

  • static generation
  • dynamically generation
  • split effect
  • icon effect
  • card effect

Let's start.


Preparation

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: listview(),
      ),
    );
  }
}


First, we create the entry point of the program, and then the listview() program that we want to show after "body".

The program recorded below all start from the entry point.


Static generation

As the name implies, the static generation is a page that does not need to dynamically adjust the length of the ListView. Usually used to display data for the user to view.

class listview extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        ListTile(title: Text('1')),
        ListTile(title: Text('2')),
        ListTile(title: Text('3')),
      ],
    );
  }
}


Output:

The static generation is the simplest method. We only need to set the ListView component on the widget, and the children of ListView set the widget, and write down the data that need to be displayed in ListTile.


Dynamically generation

Sometimes, if the data we need are too large, and the static method can not show all the data to the user at once, at this time, we need a page that can

Fortunately, in the ListView component, we can easily do this.

We modify the ListView we just wrote:

class listview extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final numbers = ['1', '2', '3', '4', '5',
                     '6', '7', '8', '9', '10',
                     '11', '12', '13', '14', '15'];
    return ListView.builder(
        itemCount: numbers.length,
        itemBuilder: (context, index){
          return ListTile(
            title: Text(numbers[index]),
          );
        }
    );
  }
}


Output:

The part that is not displayed yet, we only need to swipe down to see.

  • numbers: Store the string text we want to display
  • itemCount: The display length of the ListView element can be modified arbitrarily. If the index exceeds the length of the numbers below, an error will be reported
  • itemBuilder: Set the text displayed by the ListView component

Of course, mastering ListView.builder can generate unlimited ListView components:

class listview extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('$index'),
          );
        }
     );
  }
}


For example, like this, if itemCount is not set, the list of Index will be generated unlimitedly.


Split effect

Of course, the ListView component has a variety of display effects, the most common of which is to insert a "divider" between each row of data. If there is no such separation, it may cause visual fatigue when the user selects the data.

class listview extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return ListView.separated(
        itemCount: 100,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('row $index'),
          );
        },
      separatorBuilder: (context, index){
          return Divider();
      },
    );
  }
}


Output:

Here we are not directly setting ListView.builder just now, but setting ListView.separated-don't forget that you need to add the components returned by separatorBuilder at the bottom, so that the data can be separated and displayed smoothly.


Icon effect

Of course, ListView can not only display text, we can also add Icon beside the text to make the interface more lively.

The following is a simple example:

class listview extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        ListTile(
          leading: Icon(Icons.people),
          title: Text('Name'),
        ),
        ListTile(
          leading: Icon(Icons.calendar_view_day),
          title: Text('Age'),
        ),
        ListTile(
          leading: Icon(Icons.grade),
          title: Text('Grade'),
        )
      ],
    );
  }
}


Output:

All we need to do is to add the "leading: Icon(Icons.people)" code to the ListTile, which is a way to directly call the built-in Icon of the system.

By the way, I recommend that it is very convenient to view the effect of the icon in the IDE, even without running the program:

The icon icon can be directly displayed on the right, which is very convenient.

Of course, we can also use our own pictures. First create an assets folder under the root directory (the name can be taken by yourself, I call it assets directly), and then put the desired picture in it.

In my case, since the project I am currently working on has pictures of monster hunters, I will directly demonstrate it.

The original picture opens like this:

It is the icon of "Accessories" among monster hunters.

Then we go to pubspec.yaml (usually located under the root directory) and add the path of the image:

After adding the image path, go back to the program and use AssetImage to read the image in:

class listview extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        ListTile(
          leading: CircleAvatar(
            backgroundImage: AssetImage('assets/MHWI_0.png'),
          ),
          title: Text('Name'),
        ),
        ListTile(
          leading: CircleAvatar(
            backgroundImage: AssetImage('assets/MHWI_0.png'),
          ),
          title: Text('Age'),
        ),
        ListTile(
          leading: CircleAvatar(
            backgroundImage: AssetImage('assets/MHWI_0.png'),
          ),
          title: Text('Grade'),
        )
      ],
    );
  }
}


Output:

In this way, we can use the Icon picture we want.


Card effect

In fact, the card effect should be discussed together with the split effect, but I finally thought about it.

The card effect is to make the items on the list presented in the form of "cards", and it also brings an experience that is easier for users to view.

class listview extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    final titles = ['Name', 'Age', 'Grade'];
    final icons = [Icons.people, Icons.calendar_view_day, Icons.grade];

    return ListView.builder(
      itemCount: titles.length,
      itemBuilder: (context, index){
        return Card(
          color: Colors.lightBlueAccent,
          child: ListTile(
            leading: Icon(icons[index]),
            title: Text(titles[index]),
          )
        );
      },
    );
  }
}


Output:

The method of use is also quite simple: first store the "text" and "icon" to be displayed, and then wrap a Card layer outside our commonly used ViewTile. In order to have a good display effect, I set the background color of the card to bright blue.


The above is roughly the way to use ListView commonly used in Flutter. In fact, I started to study according to the Tutorial on the official website, and the effect of the mobile phone will report errors. Until now, I have not clarified my doubts-but fortunately, I temporarily tested the above methods of use, hoping to give the need. Some reference for people who use it.


References

Tags:

Leave a Reply