Redux App: Getting To Start

Before we begin building, let's update your counter app to a bare-bones nothing app so we can begin fresh.

1. Bare Minimum Flutter App

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

void main() => runApp(new MainApp());

class MainApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return new Container();
  }
}

NB: Container is the like <div> tag of Flutter, except you're supposed to use it. When you return a Container with children, it takes up no space. It's also a convenience widget that lets you add a ton of styles, layout, etc to it's children.

flutter run

This will give you a blank screen. But it runs.

Celebration 1: You've made a mobile app that can deploy to iOS and Android.

2. MaterialApp and Scaffold widgets

Turn that container into a MaterialApp with a title and a home:

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

void main() => runApp(new MusicParty());

class MusicParty extends StatelessWidget {
  String title = 'Me Suite';                         // new
  
  Widget build(BuildContext context) {
    return new MaterialApp(                             // updated
        title: title,                                   // new
        home: new HomePage(title),                      // new
    );
  }
}

That's it for this file, for now.

Also, we've broken the app by trying to render a widget we haven't created yet: HomePage. Let's do that.

Create a new directory called pages in the lib directory. Here, create a new file called home_page.dart;

// lib folder:
- pages
    - home_page.dart
main.dart

Now, let's build that HomePage:

// pages/home_page.dart
import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
    // We passed it a title from the app root, so we have to
    // set up the class to accept that arg.
  final String title;
  HomePage(this.title);

  
  Widget build(BuildContext context) {
    // Scaffold is almost always going to be your top-level widget
    // on each page.
    return new Scaffold(
      appBar: new AppBar(),
      body: new Container(),
      floatingActionButton: new FloatingActionButton(onPressed: null),
    );
  }
}

NB: Scaffold is a super nice widget that gives you the basic layout of almost all mobile apps. In addition to the three arguments we've passed it, it can set you up with footer navigation, a drawer where you'd put a full menu, and more.


Import your new file into main.dart. Render your app now, and it'll look like this:

screen shot blank app

We just need to fill in some of that content:

// pages/home_page.dart
import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  final String title;

  HomePage(this.title);

  
  Widget build(BuildContext context) {
    return new Scaffold(
      // AppBar class takes a Widget for title, not a string
      // In order to get it to display our title, pass it a Text widget
      appBar: new AppBar(
        title: new Text(this.title),                        // new
      ),
      body: new Container(),
      // FloatingActionButton is literally a button that floats above
      // all other page content.
      floatingActionButton: new FloatingActionButton(
        // Pass it a callback to execute when tapped
        onPressed: () => print('PRESSED!'),                 // new
        // Pass it children to render in the button
        child: new Icon(Icons.add),                         // new
      ),
    );
  }
}

With this, you now have text in app bar and a functioning floating action button. If you press it, you'll see some feedback in your console.

Finally, let's add some body content:

// pages/home_page.dart
...
  
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(this.title),
      ),
			body: new Container(
        child: new Center(
          child: new Column(
            //mainAxisAlignment is an argument for Column, Row and other
            // layout widgets. It does what CSS's 'justify-content' does
            mainAxisAlignment: MainAxisAlignment.center,
            // If you recall, Column is a layout widget that
            // expects a List who's data is of type Widget:
            children: <Widget>[
              new Text(
                'You have pushed the button this many times:',
              ),
              new Text('0'),
            ],
          ),
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: () => print('PRESSED!'),
        child: new Icon(Icons.add),
      ),
    );
  }
}

Now, save this, and refresh it. You should be back to the starter app... minus any functionality at all.

This is zero for us. Since we're implementing Redux next, we don't want to make that counter work using StatefulWidgets.