List.generate Flutter : Expense Checker App Final step

In the final step of the expense checker app we will discuss a key concept. List.generate constructor in Flutter.

Firstly, List.generate constructor generates a list of values. 

Secondly, the List.generate constructor creates the list with length position. That means the constructor fills up the list with values from index 0 but ends at the one short of the length.

Therefore the range is like this : 0 … (length – 1).

To be precise, if there is a list of 7 items, then it starts from 0 and ends at 6.

Why does this List.generate constructor play a key role in making the chart bar?

As it takes the Date time object on the one hand, and total expense on the other hand.

Let’s see the code that we have used in our code.

List<Map<String, dynamic>> get totalValuesOfTransactions {
    return List.generate(7, (index) {
      final weekDay = DateTime.now().subtract(
        Duration(days: index),
      );
      var totalSum = 0.0;

      for (var i = 0; i < latestTransactions.length; i++) {
        if (latestTransactions[i].date.day == weekDay.day &&
            latestTransactions[i].date.month == weekDay.month &&
            latestTransactions[i].date.year == weekDay.year) {
          totalSum += latestTransactions[i].amount;
        }
      }

      return {
        'day': DateFormat.E().format(weekDay).substring(0, 1),
        'amount': totalSum,
      };
    }).reversed.toList();
  }

As a result, it gives us the following output.

For example, user keeps adding the expenses, and the chart fills up with colour.

Expense Checker App - showing the expenses
Expense Checker App – showing the expenses

Let’s try to understand the List.generate constructor first. Next, we will discuss the code with a separate example.

The List.generate constructor looks as follows. 

List<E>.generate(
int length,
E generator(
int index
),
{bool growable = true}
)

In the above code we see that the List creates a data source with different types of items.

This type of data could be of any type. It can be user defined, as it can be built-in data types like integer, floating point, or string.

List.generate creates lists with different types of data

What does that mean?

Let’s try to understand this first. Since the List.generate constructor uses length and index property, we can use them to build our list.

The ListView.builder constructor will be an ideal candidate which expects a length and index to build the items.

But before that, we will create a class to create a different type of item.

abstract class ListItems {
  Widget getTitle(BuildContext context);
  Widget getSubTitle(BuildContext context);
}

Next, we will implement these abstract class methods by overriding them.

To make that happen, we need two more classes. One will display the title, and the other will display the subtitle.

class SubTitleWidget extends ListItems {
  final String subTitle;
  SubTitleWidget(this.subTitle);

  @override
  Widget getSubTitle(BuildContext context) {
    return Text(
      subTitle,
      style: GoogleFonts.laila(
        fontSize: 20.0,
      ),
    );
  }

  @override
  Widget getTitle(BuildContext context) {
    return const SizedBox.shrink();
  }
}

class TitleWidget extends ListItems {
  final String title;
  TitleWidget(this.title);

  @override
  Widget getTitle(BuildContext context) {
    return Text(
      title,
      style: GoogleFonts.laila(
        fontSize: 40.0,
      ),
    );
  }

  @override
  Widget getSubTitle(BuildContext context) {
    return const SizedBox.shrink();
  }
}

In our expense checker app, we have fetched the data from the local data source. 

But in this example, we use the type that we have declared already.

As an outcome, the tile displays the the even number and the subtitle displays the odd number.

List.generate constructor example
List.generate constructor example

We can see the code below where we have mentioned how many numbers to be displayed. 

void main() {
  runApp(
    MyApp(
      items: List<ListItems>.generate(
        11,
        (i) => i % 2 == 0
            ? TitleWidget('Even Number: $i')
            : SubTitleWidget('Odd Number: $i'),
      ),
    ),
  );
}

class MyApp extends StatelessWidget {
  final List<ListItems> items;

  const MyApp({Key? key, required this.items}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    const title = 'A List Generated Example';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: const Text(title),
        ),
        body: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {
            final item = items[index];
            return ListTile(
              title: index == 0 ? null : item.getTitle(context),
              subtitle: item.getSubTitle(context),
            );
          },
        ),
      ),
    );
  }
}

Although the above example is quite simple yet it is straightforward.

Moreover, in the light of the simple List.generate constructor example, we can try to understand how our expense checker app builds the char bar.

If you want to clone the entire project and run it on your local machine, please visit this GitHub repository.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

Courses at Educative

GitHub repository

Technical blog

Twitter

Comments

Leave a Reply