GridView Flutter: CooKingKong App – Step 1

GridView is a scrollable Widget in Flutter. It places list of elements side by side. In this section we will learn how to use the GridView while we build a recipe app. We call it “CooKingKong”.

Certainly it will not be a serious cooking lesson. Therefore do not expect to be a expert cook after finishing this module.

Let us know how this module will go. What we are going to create.

Firstly, we will have a page of Categories as follows.

GridView Flutter Recipe app first page
GridView Flutter Recipe app first page

Secondly, when we click each Category, it will take us to a page where we will find many recipes belonging to the same category.

Finally, as we click any individual item there, that will open another page where we will find the detail of the recipe.

In our previous Flutter App, “Happiness Calculator”, we have seen how we can use simple Navigation.

However, this time it will be a little different.

What is GridView Flutter and How it works

As we have said earlier, our categories page will display a List of categories.

Therefore, we need a Widget that will help us to accomplish that task. Right?

The GridView in Flutter does the same job.

It has a property called children. Subsequently, the children property expects a List of Widgets.

Let us take a look at how the GridView in Flutter looks like.

import 'package:flutter/material.dart';
import 'package:coo_king_kong/model/dummy_categories.dart';
import 'package:coo_king_kong/view/category_item.dart';

class CategoriesPage extends StatelessWidget {
  const CategoriesPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GridView(
      children: dummyCategories
          .map(
            (e) => CategoryItem(title: e.title, color: e.color),
          )
          .toList(),
      gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
        maxCrossAxisExtent: 300,
        childAspectRatio: 1.50,
        mainAxisSpacing: 20.0,
        crossAxisSpacing: 20.0,
      ),
    );
  }
}

Our top level function main() which is also the entry point, runs the “CooKingKong” App. As if you will be cooking as a King Kong. However, there is no opponent like Godzilla.

Our Widget tree runs as follows.

import 'package:flutter/material.dart';
import 'view/coo_king_kong_app.dart';

void main() {
  runApp(const CooKingKongApp());
}

class CooKingKongApp extends StatelessWidget {
  const CooKingKongApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const CooKingKongHome(),
    );
  }
}

class CooKingKongHome extends StatelessWidget {
  const CooKingKongHome({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('CooKingKong Recipe'),
      ),
      body: const CategoriesPage(),
    );
  }
}

In the above Widget tree, the last one is the CategoriesPage() which we have seen before.

But one Widget is still missing.

Because the build() method of the CategoriesPage() returns a GridView.

And, as a result, the children property of the GridView expects a List of Widgets.

That means we have to return all the categories through a class constructor as follows.

import 'package:flutter/material.dart';

class CategoryItem extends StatelessWidget {
  const CategoryItem({
    Key? key,
    required this.title,
    required this.color,
  }) : super(key: key);

  final String title;
  final Color color;

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.all(8.0),
      child: Center(
        child: Text(
          title,
          style: const TextStyle(
            fontSize: 20.0,
          ),
          textAlign: TextAlign.center,
        ),
      ),
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [
            color.withOpacity(0.6),
            color,
          ],
          begin: Alignment.bottomLeft,
          end: Alignment.topRight,
        ),
        borderRadius: BorderRadius.circular(15.0),
      ),
    );
  }
}

The above image displays this page where we have designed how each Container will look like.

We have used the decoration property of the Container class. And, in addition, the decoration property expects a BoxDecoration class.

We have discussed how we can decorate a Container before.

For example, there are other types of GridView also. There are GridView.builder, GridView.extent, and GridView.count.

We have discussed them in detail. Have a look to realise how Flutter helps us to solve problems in many ways.

Anyway, we have built the first step of CooKIngKong App. Although we have not discussed another important aspect of this module.

How did we get the List items? How each list Item has a distinct color?

Let us discuss that part as well.

Model folder is the source of data

We are following the MVC principle. Therefore, we are trying to separate data source from our Business and UI Logic.

As a result, in the Model folder, we have a Category class that has three properties.

import 'package:flutter/material.dart';

// this is first-step
class Category {
  final String id;
  final String title;
  final Color color;

  const Category({
    required this.id,
    required this.title,
    this.color = Colors.deepOrange,
  });
}

However, without a dummy category this Category class is meaningless.

For that reason, we have a List of dummy categories.

import 'package:flutter/material.dart';
import 'category.dart';

// this is first-step
const dummyCategories = [
  Category(id: 'c1', title: 'American', color: Colors.red),
  Category(id: 'c2', title: 'Mexican', color: Colors.green),
  Category(id: 'c3', title: 'African', color: Colors.blue),
  Category(id: 'c4', title: 'French', color: Colors.yellow),
  Category(id: 'c5', title: 'Chinese', color: Colors.teal),
  Category(id: 'c6', title: 'Japanese', color: Colors.amber),
  Category(id: 'c7', title: 'Indian', color: Colors.pink),
  Category(id: 'c8', title: 'Iranian', color: Colors.black12),
  Category(id: 'c9', title: 'German', color: Colors.purple),
  Category(id: 'c10', title: 'Italian', color: Colors.red),
];

Remember the CategoriesPage Widget. The children property uses this dummy data through the CategoryItem Widget constructor.

return GridView(
      children: dummyCategories
          .map(
            (e) => CategoryItem(title: e.title, color: e.color),
          )
          .toList(),
    ...

We need to understand one principle concept here.

The data source could be local. And in our case, that happens. We are using a local data source that comes from this dummy categories.

This is the simplest form. We cannot make it simpler than that.

For instance, when data comes from the backend data base, it no longer remains so simple.

With reference to that, we have discussed SQLite database and Flutter in great detail before. You may have a look.

So far, we have successfully built the first part of our “CooKIngKong” App.

If you wan to clone this part of Code, please visit this branch of GitHub repository.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

Courses at Educative

GitHub repository

Technical blog

Twitter


Posted

in

, , , ,

by

Comments

4 responses to “GridView Flutter: CooKingKong App – Step 1”

  1. […] have been building a funny recipe app in Flutter. In the first part, we have built a categories page. But in a very simple way. Now we want to use Flutter navigation to send […]

  2. […] In our App, we have only categories. And we have seen that there are many categories that we can display through GridView. […]

  3. […] Firstly, we have seen how to display all categories using the GridView. […]

  4. […] we need to understand why we want Flutter named route. Secondly, we will see how it makes our CooKingKong App more […]

Leave a Reply