#3 — Build a More Complex App
Tags: fluttercamp, flutterfyi, flutter
Published: 2018-06-19 16:18:49

---
title: #3 — Build a More Complex App
published: true
tags: fluttercamp,flutterfyi,flutter
canonical_url: https://medium.com/flutter-camp/3-build-a-more-complex-app-2165290f746
---

_This is from a series of articles I’m putting together for FlutterCamp 2018. Read more about it in the_ [_first article of the series here_](https://dev.to/devfestnyc/flutter-camp-2018-2c1k-temp-slug-4314172)_._

Woot! At this point you have your [development environment setup](https://dev.to/devfestnyc/2--getting-started-462h-temp-slug-2419028) — you verified it by creating and running your first app on a real or virtual device. Let’s keep going.

Next, we explore the [simple Startup Namer app tutorial](https://flutter.io/get-started/codelab/) to build a custom app from the scaffold. We’ll learn a bit about how Flutter apps are structured, about the importance (and power) of widgets.

_Don’t worry about the_ [_Dart_](https://dartlang.org) _syntax for now. We’ll do a deep dive on that soon. For now, know that if you have experience with Java, JavaScript or Swift, you can immediately grok the code and get a sense for the development patterns. That is all we want to achieve at this stage._

### STEP-1: Goal = Startup Namer app

This is an app that generates potential names for a new startup. We can use this to learn the following key concepts:

- **_Views & Layout_** _ — we’ll build the one in_ [this image](https://flutter.io/get-started/codelab/images/startup-namer-app.gif)
- **_Interaction Events & Handling_** _ — users can select/unselect names_
- **_Infinitely scrolling, lazily-loaded list_** _ — add 10 at a time on scroll ups_
- **_Theming_** (how to change look and feel of UI)
- **_Packages_** (and using them to to extend core Flutter functionality)

_NN> Plus, a little bit about how Flutter apps are structured, the role of widgets, state management and stateful hot reload._

### STEP-2: Starting Point = Scaffolded App

Walk through the basic steps of creating a new Flutter app as before, but call it _startup\_namer._ Open lib/main.dart, delete existing code and replace it with this code as explained [in Step 1](https://flutter.io/get-started/codelab/#step-1-create-the-starting-flutter-app).

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

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

class MyApp extends **StatelessWidget** {
  @override
**Widget build** (BuildContext context) {
    return new **MaterialApp** (
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(
          child: new Text('Hello World'),
        ),
      ),
    );
  }
}
```

_NN> This requires nothing more than delete-save-reload. No issues for me. However some observations …_

#### OBSERVATIONS:

1. **Functions vs. Classes:** Note that the same file contains both top-level functions and top-level classes._._
2. **Line 1** : `import 'package:flutter/material.dart' brings the relevant Dart packages into your codebase. In this case, we are importing the [Material package](https://flutter.io/widgets/material/) which provides all the classes (visual, behavioral and motion-rich widgets) implementing [Google’s Material Design](https://material.io/design/introduction/) for Flutter.
3. **Line 2:** `void main() => runApp(new MyApp()); is the mandatory entry point for a Flutter app. It calls the [runApp function](https://docs.flutter.io/flutter/widgets/runApp.html) which inflates the provided widget (here an instance of MyApp) and attaches it to the screen with constraints that force it to _fill the full screen._ To have a custom widget not fill the screen, wrap it in Center or Align widgets (which then fill it up)
4. **Line:** MyApp extends StatelessWidget shows that your custom widget is a Stateless one; we’ll learn about Stateless & Stateful widgets later.
5. **Everything in Flutter is a widget; everything.** The style (alignment, padding etc.), the layout, the behaviors (gesture, touch etc.) are all widgets. And UI development is all about widget composition. The key is the **build** function that describes how to assemble that widget’s subtree (from lower-level widgets). _To learn how Flutter transforms a widget tree into pixels on a screen,_ [_watch this talk_](https://www.youtube.com/watch?v=UUfXWzp0-DU)_._
6. **MaterialApp, Scaffold & AppBar.** [MaterialApp](https://docs.flutter.io/flutter/material/MaterialApp-class.html') is a stateful convenience widget that wraps a number of widgets commonly required for Material Design. It also works with the top-level Navigator to map routes correctly.

### STEP-3: Dependencies = Add external package

Many third-party Dart packages for Flutter exist on [pub.dartlang.org](https://pub.dartlang.org/flutter/). Work through [the Step 2 directions](https://flutter.io/get-started/codelab/#step-2-use-an-external-package) to add the _english\_words_ package and use that to randomly select a new english word to show in the onscreen message.

**Steps:**  
1. Add english\_words dependency in **pubspec.yaml  
2.** When in that file, click _get package icon_ (top right) to fetch the package  
3. Add import 'package:english\_words/english\_words.dart'; in main.dart  
4. Then use it e.g., final wordPair = new WordPair.random();

_NN> This was a fairly painless process for me. No issues. Things to explore: what happens when an imported package has its own dependencies?_

### STEP-3: Stateful Widget = Add new

Work through [the Step 3 directions](https://flutter.io/get-started/codelab/#step-3-add-a-stateful-widget) to build out the first Stateful Widget.

_NN> This was also a straightforward step. But let’s spend a few minutes here talking about some interesting aspects._

#### OBSERVATIONS:

1. You can define multiple classes and functions in the same source file.
2. The StatefulWidget does little more beyond creating its associated State instance; it’s the latter that does the heavy lifting on widget creation here.
3. Both the StatelessWidget and StatefulWidget _classes_ are immutable; their properties cannot be changed once created. The latter however has an associated mutable State object that persists for the lifetime of the widget.
4. You can see how your UI can be iteratively designed and built by composing it out of lower-level stateful and stateless widgets. We’ll talk about state management later.

### STEP-4: List View = Infinite Scroll

Work through[step 4 of the tutorial](https://flutter.io/get-started/codelab/#step-4-create-an-infinite-scrolling-listview) to create a list of names that the user can scroll through, infinitely.

_NN> This was also a straightforward step. But the interaction between the ListView, the ListView.builder and the helper “\_build” functions can be a bit complicated to untangle._

#### OBSERVATIONS:

1. **Private Variables.** In Dart, prefixing a variable with an underscore (\_) automatically makes that a private variable. So here, a number of defined class variables and functions are visible only within the class/instance.
2. **Everything’s a Widget.** And widgets can be composed of other widgets to create custom complex views. And so on until you get to the lowest-level (nodes) where you’ll likely be using [a standard Flutter widget](https://flutter.io/widgets/) as core. So one way to develop UI is to start by returning a core widget from the build method — then refactoring just that method to wrap the core widget in another widget that provides additional capability; this could for example be a container widget which now lets you return a complex or managed layout instead of a single widget.
3. [**ListView**](https://docs.flutter.io/flutter/widgets/ListView-class.html) is a widget that represents a scrollable set of widgets arranged linearly —when using builder (itemBuilder) it takes a context and an index that increases monotonically. You simply return the ListTile widget for that index if you can create one — so you can create an infinitely scrolling list if you make sure you always return something for each index.

_The main thing to look at and understand here is that the code looks more complex than it is because it has all been inlined. Later, we can see how we can make the code clearer to read by simply abstracting out some of this into private functions that are invoked instead._

### STEP-5: Interactivity = Event handling

Work through [step 5 of the tutorial.](https://flutter.io/get-started/codelab/#step-5-add-interactivity)

_NN> This was also a straightforward step. The key to understand here is the usage of setState() to trigger state changes, which in turn cause render tree to be re-evaluated and re-rendered with the updated state. In this case, it means we go from showing a clear heart to a colored heart (or vice versa) after each click._

### STEP-6: Navigation = Route handling

Work through[step 6 of the tutorial](https://flutter.io/get-started/codelab/#step-6-navigate-to-a-new-screen)

_NN> This is an interesting step to stop and think about since it’s the first place where navigation enters the equation. Let’s talk about Navigator, MaterialApp and the MaterialPageRoute first, then look at code._

**The** [**Navigator**](https://docs.flutter.io/flutter/widgets/Navigator-class.html) **:** is a Flutter core widget that manages a set of child widgets as a “stack” using [an Overlay](https://docs.flutter.io/flutter/widgets/Overlay-class.html) pattern. Overlay allows a widget to be floated above another, to showcase relative importance or provide visual transition effects. If widgets are full-screen, then Navigator effectively creates the illusion of moving from screen to screen (pages) by floating widgets up and down in the Overlay.

_This is how routing gets handled (with widgets mapped to routes).This behavior will be very familiar to web developers particularly given the named routes use the path/a/b/c structure for_ **_named routes._**

[**MaterialApp:**](https://docs.flutter.io/flutter/material/MaterialApp-class.html)You can create a Navigator for your app, or use one from MaterialApp or WidgetsApp (if they are managing the root of your widget tree). Use Navigator.push(context, new MaterialPageRoute<void>( ... )) to push a new route onto the stack on demand; the MaterialPageRoute takes a builder function which can create the page (widget) to show, and also handle the Navigator.pop(context) behavior to return “back” to the previous screen.

_If you use MaterialApp with Scaffold, it automatically adds a”back” button in AppBar that pops the Navigator stack for you in any context._

[**Routes can return a value.**](https://docs.flutter.io/flutter/widgets/Navigator-class.html) This is cool. It is analogous to _startActivityFor Result_ in Android where, when you trigger the new screen (Navigator.push) you do so with the intent of taking the user to a new screen from which you expect a result to be returned when he is don (Navigator.pop).

_There is also support for popup routes (modal part-screen overlays) and custom routes (to control the animations on transition for that route)._

### STEP-7: Theming = Changing look & feel

Work through [step 7 of the tutorial](https://flutter.io/get-started/codelab/#step-7-change-the-ui-using-themes)

_NN> Theme controls look & feel of the app. Changing an app’s theme is as simple as configuring the ThemeData class at the top-level widget (e.g., MaterialApp)._

**Exercise** : Check out [ThemeData](https://docs.flutter.io/flutter/material/ThemeData-class.html) capabilities and make other changes to see how you can customize the theme more rigorously. Here is the list of attributes that can be changed:

```
[ThemeData](https://docs.flutter.io/flutter/material/ThemeData/ThemeData.html)({

[Brightness](https://docs.flutter.io/flutter/services/Brightness-class.html) brightness, 
[MaterialColor](https://docs.flutter.io/flutter/material/MaterialColor-class.html) primarySwatch, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) primaryColor,
[Brightness](https://docs.flutter.io/flutter/services/Brightness-class.html) primaryColorBrightness, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) primaryColorLight, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) primaryColorDark, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) accentColor, 
[Brightness](https://docs.flutter.io/flutter/services/Brightness-class.html) accentColorBrightness, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) canvasColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) scaffoldBackgroundColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) bottomAppBarColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) cardColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) dividerColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) highlightColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) splashColor, 
[InteractiveInkFeatureFactory](https://docs.flutter.io/flutter/material/InteractiveInkFeatureFactory-class.html) splashFactory, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) selectedRowColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) unselectedWidgetColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) disabledColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) buttonColor, 
[ButtonThemeData](https://docs.flutter.io/flutter/material/ButtonThemeData-class.html) buttonTheme, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) secondaryHeaderColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) textSelectionColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) textSelectionHandleColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) backgroundColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) dialogBackgroundColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) indicatorColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) hintColor, 
[Color](https://docs.flutter.io/flutter/dart-ui/Color-class.html) errorColor, 
[String](https://docs.flutter.io/flutter/dart-core/String-class.html) fontFamily, 
[TextTheme](https://docs.flutter.io/flutter/material/TextTheme-class.html) textTheme, 
[TextTheme](https://docs.flutter.io/flutter/material/TextTheme-class.html) primaryTextTheme, 
[TextTheme](https://docs.flutter.io/flutter/material/TextTheme-class.html) accentTextTheme, 
[InputDecorationTheme](https://docs.flutter.io/flutter/material/InputDecorationTheme-class.html) inputDecorationTheme, 
[IconThemeData](https://docs.flutter.io/flutter/widgets/IconThemeData-class.html) iconTheme, 
[IconThemeData](https://docs.flutter.io/flutter/widgets/IconThemeData-class.html) primaryIconTheme, 
[IconThemeData](https://docs.flutter.io/flutter/widgets/IconThemeData-class.html) accentIconTheme, 
[SliderThemeData](https://docs.flutter.io/flutter/material/SliderThemeData-class.html) sliderTheme, 
[ChipThemeData](https://docs.flutter.io/flutter/material/ChipThemeData-class.html) chipTheme, 
[TargetPlatform](https://docs.flutter.io/flutter/foundation/TargetPlatform-class.html) platform 

})
```

### ERROR: How do you know something’s wrong?

The awesome thing about Flutter development is that the simulator/emulator immediately provides feedback through the _red screen of death._ The descriptions are verbose giving you insights into where the problem lies.

![](https://cdn-images-1.medium.com/max/974/1*xwP6l8FtAOUAIPT9-d84lQ.png)<figcaption>The red screen of death</figcaption>

You can quickly explore ideas by undoing recent changes, commenting-out and modifying the sections identified (e,g, if the offending widget is RandomWords, start there..). Hot reload makes it possible to track and fix at least UI related errors, relatively quickly.

### EXPLORATION IDEAS

_Try out some of these things to get a better sense for the development environment:_

1. **Change ThemeData** properties and see how that affects
2. Change **the ListView builder** to use a different kind of item widget. See how that impacts the scrolling and appearance.
3. **Explore routing options**. Try to create a new route and associated widget and see if you get the default Back behavior.

### OPEN ISSUES

_I’ll use this section to capture any issues experienced by attendees at the workshop. In particular, I am interested in seeing if the process/experience for attendees on Windows or Linux development environments is as painless._

* * *