Flutter UI Widgets

Nov 9 2021 Dart 2.14, Flutter 2.5, VS Code 1.61

Part 1: Flutter UI Widgets

2. Explore Basic Widgets

Episode complete

Play next episode

Next
About this episode
See versions

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 1. Understand Flutter's UI Approach Next episode: 3. Build Layouts

This video Explore Basic Widgets was last updated on Nov 9 2021

Open the starter project for this episode in Visual Studio Code. I’m using version 1.60. Inside the main.dart file, you have the main method that runs the root widget of the application. The root widget; MyApp which is a stateless widget returns an empty Container in its build method. More on the Container widget later on.

Update the build method as follows:

...
  return const MaterialApp(
    title: 'Flutter UI Widgets',
    home: MainPage(),
  );
...

Here, we returned a MaterialApp and set its title and home properties to “Flutter UI Widgets” and MainPage() respectively.

The title is used by the device to identify the app. For example, the title is displayed beside the app snapshot when the user presses the “recent apps” button on Android devices. The display name can also be set in the AndroidManifest.xml file.

Note that on iOS devices, the MaterialApp’s title is not used. Instead you’ll have to set the string of the CFBundleName key in the Info.plist file for it to appear on the open apps list.

Next, we set the home to MainPage which is the default route that would be loaded when the app starts. Flutter offers us the Material component library and Cupertino widgets. Material is based on Google’s design specification for creating user interfaces while Cupertino provides iOS-style widgets.

We would be using MaterialApp since it is optimized for all platforms then later we’ll explore some Cupertino widgets. Let’s create the MainPage widget. Inside the lib folder, go ahead and create main_page.dart file inside a new folder named “pages”.

Update the file as follows:

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter UI Widgets'),
      ),
      body: const Center(
        child: Text('Main Page'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          print('Clicked');
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

Here we returned a Scaffold which is just a layout structure for an app screen that implements material design guideline. The AppBar returns a Text widget as its title. The body return a Text widget that is placed at the center of the screen with the Center widget.

Finally, the FloatingActionButton returns an Icon as its child widget. It also has an onPressed callback that is executed when this button is pressed. Flutter provides us with some interaction widgets and FloatingActionButton is one of them. We’ll be talking more about adding interactions later in this course.

Save this file. Then head back to the main.dart file and fix the import for the main page. After that, hit the F5 key to run the app in debug mode. You can see the corresponding widget shows up in the app.

Note, in Flutter everything is a widget. To an extent, a Widget can be likened to a View or UIView in Android and iOS respectively. They are not exactly the same but the idea can be useful while getting used to how UIs are constructed in Flutter.

Next, let’s explore the Container widget. Update your code as follows:

...
return Container(
  margin: cosnt EdgeInsets.all(32),
  padding: cosnt EdgeInsets.all(16),
  width: 200,
  height: 200,
  color: Colors.green,
  child: const Text('Main Page'),
)
...

Save the file. A Container can be used for sizing, painting and to house other widgets. Here, we give it a margin of 32 and a padding of 16. A width and height of 200. We set the color to green and passed in a Text as its child. A padding is the internal space between the Container and its children. While the margin is the space from the external bounds of the container to its suroundings.

To utilizie more of its painting capabilities, we use the decoration property. Update the Container as follows:

...
decoration: BoxDecoration(
  borderRadius: BorderRadius.circular(16),
  border: Border.all(width: 2.0, color: Colors.red),
  color: Colors.green,
),
...

For this code to work, you’ll have to comment out the color property of the Container because it is simply a shortcut for a decoration with a background color.

Save your work. The BoxDecoration class provides ways to paint and draw a box. Here, we used it to add a circular borderRadius and a red border around the Container. It also has additional properties for image, padding, gradients and others.

If you’re coming from the Android ecosystem, you use LinearLayout to lay out Views horizontally or vertically. In Flutter, you use the Row and Column widgets. Update your code to use a Column:

...
child: Column(
  children: <Widget>[
    const Text('1'),
    const Text('2'),
    const Text('3'),
  ],
),
...

Save the file. You can see that the items are arranged vertically. To increase the fontSize, update the code as follows:

const Text('1', style: TextStyle(fontSize: 32)),
const Text('2', style: TextStyle(fontSize: 32)),
const Text('3', style: TextStyle(fontSize: 32)),

You style texts with the TextStyle class. To align its children along its main axis, you use the mainAxisAlignment. Set it up as follows:

mainAxisAlignment: MainAxisAlignment.spaceEvenly,

This adds equal spaces between the children. Note, the main axis of a Column is the vertical axis. The mainAxisAlignment can be set to other values.

And here are the different options you can set. I’ll leave you to play around with them. To align its children along its crosss axis, you use the crossAxisAlignment. Here, the cross axis would be the horizontal axis since it is a Column. Add the following code:

crossAxisAlignment: CrossAxisAlignment.stretch

This sets the children to stretch across the horizontal axis. We can’t really see the effect right now. Let’s wrap the text with a Container and give it a background color. Update your code to the following:

Container(
  color: Colors.blue,
  child: const Text(
    '1',
    textAlign: TextAlign.center,
    style: TextStyle(fontSize: 32),
  ),
),
// Repeat this for the remaining 2 

Save you work. And you can see that the children now stretches from the start to the end along its cross axis. Commenting out the crossAxisAlignment would show you the difference. So without the cross axis.

And with the cross axis.

We can also align the text to the center. We already did that and you see the code here. So if i comment it out,you can see the difference. I’ll put that back in. Add an alignment to the Text widget like so:

textAlign: TextAlign.center

Save your work and you should see the changes. Next is the Row widget. It is similar to the Column widget but arranges its children horizontally. And its alignment axes are the opposite of the Column widget.

Change your Column to a Row. Save your work and you can see it inverts the alignments and arranges the children horizontally. Also, the mainAxis is aligned to space each child evenly. And commenting out the crossAxisAlingnment places the children at the start of the vertical axis. (Do it)