# Build a Two Screen Flutter Application - GSP1010

## Overview

Flutter is Google's UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source.

In this lab, you will create a Flutter app using generated template code. The basic Flutter interface provides a simple example to get started programming in Flutter.

![Flutter interface](https://cdn.qwiklabs.com/rl9Z%2BvRcod8mMOEATzaUo0LIEqnVIKlEP6eNNTBMJ5E%3D align="left")

### What you'll learn

* How to write a Flutter app that looks natural on iOS, Android, and the web
    
* Basic structure of a Flutter app
    
* Using multiple pages
    
* Using hot reload for a quicker development cycle
    

### Prerequisites

Based on the content, it is recommended to have some familiarity with:

* Flutter
    
* Dart
    

## Task 1. Open the Code Server Editor

In this lab, you will use a custom editor that includes the Flutter and Dart extensions. From the initial lab panel:

![Lab Details pane with the IDE and teh Live Server addresses](https://cdn.qwiklabs.com/dS9s9A4jV8gOitYPn9bza6lrsxf0JUsXrSUiKElg%2FSU%3D align="left")

1. Copy the Flutter IDE address displayed
    
2. Paste the IDE address into a Browser tab
    

## Task 2. Creating a Flutter template

In this section, create a Flutter Web application called first\_app.

1. Click the hamburger button in the top left () and then click **Terminal &gt; New Terminal**.
    
2. In the terminal, enter the following command:
    

```apache
flutter create first_app
```

4. Move to the first\_app directory:
    

```apache
cd first_app
```

5. Close the terminal window:
    

```apache
exit
```

The `first_app` directory and template code have now been created.

## Task 3. Opening the new app

In this section, explore the Flutter Web application called first\_app.

1. Open the folder `first_app`.
    
2. Acknowledge the on-screen notifications.
    

At this point, you will have the Flutter application open in the current workspace.

## Task 4. Running the Flutter web application

In this section, run the Flutter Web application from the command line.

1. In the editor, open a Terminal.
    
2. Ensure the terminal directory is set to `first_app`.
    
3. Run the Flutter web server:
    

```apache
fwr
```

4. The running web server should look similar to below:
    

![Output indicating the web server is running](https://cdn.qwiklabs.com/KumcS%2BFTd5wF7eaee%2FARj%2F6Oc2hTg3E9UwYNERfTKvI%3D align="left")

5. Copy the Flutter Live Server address from the lab Panel.
    
6. Paste the address into a new browser tab.
    
7. The browser will render the web application e.g.
    

**Note:** Rendering of the web application can take up to ten seconds. The view will show the application based on the code in the editor.

Feel free to interact with the running application.

## Task 5. Designing the application

In this section, use widgets to build a basic two screen application.

![Illustration of a basic two-screen application](https://cdn.qwiklabs.com/nJdxtwYrLNngyH%2FVrYIx1ITmPXUI6NSTUhoBFoRYI5o%3D align="left")

From the above sketch, we note that our application uses the following types of widgets.

| **Widget** | **Description** |
| --- | --- |
| AppBar | Header bar |
| Scaffold | Screen layout |
| Text | Text entry fields |
| ListView | Item list |

## Task 6. Working with ListView

In this section to build a basic item list, the Flutter page will look similar to the image below:

![My Awesome App list with seven items, January, February, March, April, May, June, and July](https://cdn.qwiklabs.com/0qXHf9p%2Fglpun4GbEl1NyKeZ1nE%2FIeNmbU1JF9YiP1c%3D align="left")

In the image, there is a list of months presented. A ListView widget is capable of listing items.

```javascript
body: ListView(
  children: <Widget>[
    ListTile(
      title: Text('January'),
    ),
    ListTile(
      title: Text('February'),
    ),
    ListTile(
      title: Text('March'),
    ),
  ],
),
```

To learn more, refer to [Lists](https://flutter.dev/docs/cookbook/lists) in the Flutter documentation. In the exercise below, create a [basic short list](https://flutter.dev/docs/cookbook/lists/basic-list).

1. Begin by replacing the template code in `main.dart` with the code below:
    

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final title = 'MyAwesome App';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: ListView(
          children: <Widget>[
            ListTile(
              title: Text('January'),
            ),
            ListTile(
              title: Text('February'),
            ),
            ListTile(
              title: Text('March'),
            ),
          ],
        ),
      ),
    );
  }
}
```

2. Save the updated code.
    
3. Click in the open Terminal window, and press ‘r'.
    
4. Switch to the `Flutter Device` browser tab.
    
5. Press `CTRL+R` to reload the page.
    

The code in the above example creates a basic list. Similar to our application sketch, this presents data as outlined in our design.

## Task 7. Managing ListView data

In this section, add user interaction to respond when a list item is selected.

Previously, we have looked at using a small amount of data being added to a ListView. Working with larger volumes of data can be challenging. To help with this situation, consider the ListView.builder.

1. Declare a List:
    

```dart
final List<String> items = ['January', 'February', 'March'];
```

2. ListView.builder declaration:
    

```dart
body: ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text('${items[index]}'),
    );
  },
),
```

In this exercise below, create a [long list](https://flutter.dev/docs/cookbook/lists/long-lists) using a ListView.builder.

1. Replace the `MyApp` class with the code below:
    

```dart
class MyApp extends StatelessWidget {
  final List<String> items = ['January', 'February', 'March'];

  @override
  Widget build(BuildContext context) {
    final title = 'MyAwesome App';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text('${items[index]}'),
            );
          },
        ),
      ),
    );
  }
}
```

2. Click in the open Terminal window, and press ‘r'.
    
3. Switch to the `Flutter Device` browser tab.
    
4. Press `CTRL+R` to reload the page.
    

The code in this example creates a long list using the ListView.builder. The page rendered is exactly the same as before. However, this is a better approach to handling larger data sources.

## Task 8. Adding interactivity

In this section, add user interaction to respond when a list item is selected. Add interactivity in Flutter typically requires a [Gesture Detector](https://flutter.dev/docs/development/ui/advanced/gestures). The type of gesture to capture is called a Tap.

Additionally, add a [SnackBar](https://flutter.dev/docs/cookbook/gestures/handling-taps) to the code so there is a visual notification when a user taps on a list item.

```dart
onTap: () {
  final snackBar = SnackBar(content: Text('You selected $items[index]'));
  ScaffoldMessenger.of(context).showSnackBar(snackBar);
},
```

In this exercise, the `MyApp` class with the following code:

1. Update `MyApp` with the following code:
    

```dart
class MyApp extends StatelessWidget {
  final List<String> items = ['January', 'February', 'March'];

  @override
  Widget build(BuildContext context) {
    final title = 'MyAwesome App';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text('${items[index]}'),
              // When the child is tapped, show a snackbar.
              onTap: () {
                final snackBar = SnackBar(content: Text('You selected $items[index]'));
                ScaffoldMessenger.of(context).showSnackBar(snackBar);
              },
            );
          },
        ),
      ),
    );
  }
}
```

**Note:** The onTap resides in the ListTile widget as an accepted parameter. Tapping on a list item will then register as a tap and invoke the SnackBar.

The implementation of the SnackBar is temporary to provide feedback that our onTap is working correctly.

2. Click in the open Terminal window, and press ‘r'.
    
3. Switch to the `Flutter Device` browser tab.
    
4. Press `CTRL+R` to reload the page.
    

**Note:** The onTap also provides a visual cue to indicate an action is available for the list item.

Hover over each item to see the mouse pointer change.

## Task 9. Creating a details page

In this section, create a second Flutter page and display some more information.

![Details page illustration](https://cdn.qwiklabs.com/tQdL%2BpGaMgIiB4KHYG%2FwG8wpDQapxzjIWH4SpgGhxzw%3D align="left")

As the second page is very similar to the first page, this can help us construct the code.

* In this exercise, add the following functionality to the `main.dart` file:
    

```dart
class MyDetails extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    final title = 'Details Page';

    return Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: Text('You selected January'),
    );
  }
}
```

**Note:** The widget returned is a Scaffold. In the application there should be only one MaterialApp defined. Now the MaterialApp widget will be able to handle navigation properly in the application.

At this point, the `Details Page` is not connected to the first page. You'll correct that in the next section.

## Task 10. Navigating between pages

In this section, enable [navigation](https://flutter.dev/docs/cookbook/navigation) between the first page and the second:

```javascript
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => MyDetails()),
);
```

Previously, we enabled a SnackBar to indicate that an onTap event had occurred. To achieve navigation will require the following activities:

* Remove the SnackBar code
    
* Add a [navigation between the pages](https://flutter.dev/docs/cookbook/navigation/navigation-basics)
    
* Point the navigation to the `MyDetails` class
    

1. Add a Navigator.push to `MyApp`:
    

```javascript
class MyApp extends StatelessWidget {
  final List<String> items = ['January', 'February', 'March'];

  @override
  Widget build(BuildContext context) {
    final title = 'MyAwesome App';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text('${items[index]}'),
              // When the child is tapped, show a snackbar.
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => MyDetails()),
                );
              },
            );
          },
        ),
      ),
    );
  }
}
```

2. Click in the open Terminal window, and press ‘r'.
    
3. Switch to the `Flutter Device` browser tab.
    
4. Press `CTRL+R` to reload the page.
    

![Illustration of basic two screen application](https://cdn.qwiklabs.com/nJdxtwYrLNngyH%2FVrYIx1ITmPXUI6NSTUhoBFoRYI5o%3D align="left")

Now, the application will be able to move between the Main page and the Details page. However, the details page always says January. You'll fix that in the next section.

## Task 11. Passing data between pages

In this section, learn how to pass information between pages.

* Update the navigation code to pass a parameter:
    

```javascript
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => MyDetails(items[index])),
);
```

### MyApp

In the code below, use MaterialPageRoute to communicate with your new page. To pass information to the Details page, we use the list item string as a parameter.

* Update `MyApp` to call `MyDetails` with a parameter:
    

```javascript
class MyApp extends StatelessWidget {
  final List<String> items = ['January', 'February', 'March'];

  @override
  Widget build(BuildContext context) {
    final title = 'MyAwesome App';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text('${items[index]}'),
              // When the child is tapped, show a snackbar.
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => MyDetails(items[index])),
                );
              },
            );
          },
        ),
      ),
    );
  }
}
```

### MyDetails

Now that `MyApp` expects to pass data to the `MyDetails` class. Make the following updates to accept a parameter using a Constructor.

1. A Constructor is used to accept the parameter i.e. the list item.
    

```apache
MyDetails(this.month);
```

2. A variable is used to hold the information passed as a parameter.
    

```apache
final String month;
```

3. The Text widget is used to display the information passed.
    

```apache
body: Text('You selected $month'),
```

To make the changes, follow the steps below:

1. Update `MyDetails` to accept a parameter:
    

```apache
class MyDetails extends StatelessWidget {
  final String month;
  MyDetails(this.month);

  @override
  Widget build(BuildContext context) {
    final title = 'Details Page';

    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Text('You selected $month'),
    );
  }
}
```

2. Click in the open Terminal window, and press ‘r'.
    
3. Switch to the `Flutter Device` browser tab.
    
4. Press `CTRL+R` to reload the page:
    

![Details Page that displays: You selected January](https://cdn.qwiklabs.com/NAxODPMQBZf1fXM6cUM%2F%2FjcEIm%2BrHSWuJdxOqseFJXE%3D align="left")

**Note:** With the string parameter available in MyDetails, the Text widget can use the variable `month` and display it to the user.

Click **Check my progress** to verify the objective.

Assess my progress

---

## Solution of Lab

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1756007140572/19ebeee2-c192-4555-a26a-5c8e88ba5f44.png align="center")
