Layout Basics
Flutter Crash Course: "02 - Layout Basics"
Summary
we'll take a first look at the mockups we want to implement for this course for our "Tourism & Co." app. We'll start to implement the "detail screen" of the app, where an image is shown at the top along with some text below. We'll cover some Flutter layout concepts to ensure our page's content is laid out properly.
In this lesson we'll cover: working with layout using Column
, mainAxisAlignment
and crossAxisAlignment
The Code for This Lesson
Check out the tourismandco repo's step/step02
branch for the code we'll cover in this lesson.
What We're Working Toward
We'll be implementing three text sections which will be part of our "Location Detail" screen for the Tourism & Co. app. Later, these text sections will be dynamic but for now, we'll just create three so that text sections of our screen has its own widget.
Basic Layout Concepts in Flutter
Layout controls the way content in your is constraied or expands in a given area. Your app can be shown on various screen sizes, can be rotated and content can change dynamically. Content can be images, text, buttons or really anything. It's important to ensure this content is nicely contained to the user.
The most common layout pattern, especially for mobile phones in particular, is a "Column" of content, where each item in the column flows from top to bottom. For this type of layout, Flutter defines something called the "main axis", which for a Column is a vertical line going through the widget. For other widgets, such as the Row widget, this "main axis" also exists, but is instead a horizontal row going from left to right of the widget.
We also have the converse of "main axis" which is the "cross axis". In other words, this is the "other" axis of a given layout widget. So for Column, the "cross axis" is a horizontal line going through each child of Column. For Row, it'd instead be a vertical line going through each child.
Layout using Column
, mainAxisAlignment
and crossAxisAlignment
- Take a look at
https://github.com/seenickcode/tourismandco/*.png
in this repo to see the screenshots of what we'll implement in this course. - Rename
home/home.dart
tolocation_detail/location_detail.dart
as well as the class name. This will our "location detail" screen of our tourism app. - Let's implement four individual sections of our screen, where the first will soon contain an image and the rest will contain some text.
Using the Column
Widget
- Implement
_bannerContainer()
and_textSectionContainer()
, each with a simple container andBoxDecoration
.- This way, we can visually see how layout will affect our content.
- Add a
Column
widget to the main body.- The
Column
widget is used to present content in a single column, where eachchild
widget is laid out from top to bottom. mainAxisAlignment
allows us to control how eachchild
of aColumn
is laid out from top to bottom. The "main axis" is essentially a vertical line going through the center of ourColumn
.crossAxisAlignment
controls how content is aligned for each individualchild
of theColumn
.
- The
// location_detail/location_detail.dart
// WARNING: not the final implementation of this lesson
import 'package:flutter/material.dart';
import 'text_section.dart';
class LocationDetail extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Hello'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
decoration: BoxDecoration(
color: Colors.red,
),
child: Text('hi'),
),
Container(
decoration: BoxDecoration(
color: Colors.green,
),
child: Text('hi'),
),
Container(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text('hi'),
),
],
));
}
}
Here we define a few text sections, using the Column
widget. We're showing a block of color using the Container
widget, where each block is a different color. This will help us see the different layout options we have available to us by changing mainAxisAlignment
and crossAxisAlignment
.
Notice what happens when you use:
MainAxisAlignment.spaceEvenly
MainAxisAlignment.end
CrossAxisAlignment.center
CrossAxisAlignment.end
- Try removing
mainAxisAlignment
andcrossAxisAlignment
params altogether!
Implementing our own Parameterized Widget, TextSection
After playing around with our Column
widget, let's clean up our code. We'll implement our own new StatelessWidget
so we can re-use our code.
// location_detail/text_section.dart
import 'package:flutter/material.dart';
class TextSection extends StatelessWidget {
final Color _color;
TextSection(this._color);
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: _color,
),
child: Text('hi'),
);
}
}
Finally, let's update our location_detail/location_detail.dart
file to use our new widget:
// location_detail/location_detail.dart
import 'package:flutter/material.dart';
import 'text_section.dart';
class LocationDetail extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Hello'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextSection(Colors.red),
TextSection(Colors.green),
TextSection(Colors.blue),
],
));
}
}
Lastly, let's update our app.dart
file to:
// app.dart
import 'package:flutter/material.dart';
import 'screens/location_detail/location_detail.dart';
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: LocationDetail(),
);
}
}
Summary
We can now implement the real content of our screen, now that our layout is defined.