“30 Days Of Flutter” with FlutLab: Code Party 6
We finished 1/3 of the whole path in our #30DaysOfFlutter journey. Flutter Developers team and Flutter Community doing all possible to make this journey useful and fun. Live Stream Guests are throwing out some fantastic insides and motivating us to move forward. I think we’ll miss all of them after the finish of our journey.
FlutLab can make your start in Flutter even easier. So, if you are ready to continue our “Code Parties”, open a new tab in your favorite browser and enter https://flutlab.io
Our “Code Party” must go on …
You have 3 options here to get to speed with our current project:
- Get Part 2 from Widget Bay https://widgetbay.flutlab.io/widget/shrine---part-2
2. Get Part 2 from GitHub https://github.com/mdrobnych/mdc_100_series_part_2
3. Start from the ground:
No matter how you started your journey, you will end up with our working project. Click the “Build Project” button to run it. You can click the “Next” button inside the Web Emulator to see the project in action.
I hope you like this app and can’t wait to make it even better.
- Let’s add more colors to the app for fun. Click at lib folder. You will see some additional icons. Click at the “Create File” icon.
2. You have to create colors.dart
file
3. After the creation of the file, add the following content to it:
import 'package:flutter/material.dart';
const kShrinePink50 = Color(0xFFFEEAE6);
const kShrinePink100 = Color(0xFFFEDBD0);
const kShrinePink300 = Color(0xFFFBB8AC);
const kShrinePink400 = Color(0xFFEAA4A4);
const kShrineBrown900 = Color(0xFF442B2D);
const kShrineErrorRed = Color(0xFFC5032B);
const kShrineSurfaceWhite = Color(0xFFFFFBFA);
const kShrineBackgroundWhite = Colors.white;
Color and ColorSwatch constants from Color class represent Material design’s color palette.
4. Let’s import colors.dart
into the app.dart.
Learn more about ThemeData in the Flutter documentation.
import 'colors.dart';
5. Find this line of code // TODO: Build a Shrine Theme (103)
inside the app.dart
and add the following fragment below (CTRL+S for save):
final ThemeData _kShrineTheme = _buildShrineTheme();
ThemeData _buildShrineTheme() {
final ThemeData base = ThemeData.light();
return base.copyWith(
accentColor: kShrineBrown900,
primaryColor: kShrinePink100,
buttonTheme: base.buttonTheme.copyWith(
buttonColor: kShrinePink100,
colorScheme: base.colorScheme.copyWith(
secondary: kShrineBrown900,
),
),
buttonBarTheme: base.buttonBarTheme.copyWith(
buttonTextTheme: ButtonTextTheme.accent,
),
scaffoldBackgroundColor: kShrineBackgroundWhite,
cardColor: kShrineBackgroundWhite,
textSelectionColor: kShrinePink100,
errorColor: kShrineErrorRed,
// TODO: Add the text themes (103)
// TODO: Add the icon themes (103)
// TODO: Decorate the inputs (103)
);
}
6. The next small step is to set up the theme for our app. Find the // TODO: Add a theme (103)
line in app.dart
and add this line below: theme: _kShrineTheme,
Beautiful! Now click the “Build Project” button.
7. We have added colors to our app. Now it’s time to play with app’s fonts. Open pubspec.yaml
. Find the # TODO: Insert Fonts (103)
line and add the location of your fonts:
fonts:
- family: Rubik
fonts:
- asset: fonts/Rubik-Regular.ttf
- asset: fonts/Rubik-Medium.ttf
weight: 500
By the way, you can preview the font in FutLab.
8. Open login.dart
file
Remove this lines
Column(
children: <Widget>[
Image.asset('assets/diamond.png'),
SizedBox(height: 16.0),
Text('SHRINE'),
],
),
And add this instead
Column(
children: <Widget>[
Image.asset('assets/diamond.png'),
SizedBox(height: 16.0),
Text(
'SHRINE',
style: Theme.of(context).textTheme.headline5,
),
],
),
9. Find the // TODO: Build a Shrine Text Theme (103)
line in app.dart
and add this fragment
TextTheme _buildShrineTextTheme(TextTheme base) {
return base.copyWith(
headline5: base.headline5.copyWith(
fontWeight: FontWeight.w500,
),
headline6: base.headline6.copyWith(
fontSize: 18.0
),
caption: base.caption.copyWith(
fontWeight: FontWeight.w400,
fontSize: 14.0,
),
bodyText1: base.bodyText1.copyWith(
fontWeight: FontWeight.w500,
fontSize: 16.0,
),
).apply(
fontFamily: 'Rubik',
displayColor: kShrineBrown900,
bodyColor: kShrineBrown900,
);
}
TextTheme class defines the various typographical styles found in Material Design (e.g., button, caption).
10. Add the following themes to _buildShrineTheme
.
Find the // TODO: Add the text themes (103)
line and add a new theme to the text:
textTheme: _buildShrineTextTheme(base.textTheme),
primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme),
accentTextTheme: _buildShrineTextTheme(base.accentTextTheme),
Find the // TODO: Add the icon theme (103)
line and add a new theme to the icon:
primaryIconTheme: base.iconTheme.copyWith(
color: kShrineBrown900
),
Awesome! Good Job. It’s time to see the results of our work. Click the “Hot Reload” or the “Build Project” button.
11. Let’s add more beauty to the product labels.
In home.dart
find the // TODO: Change innermost Column (103)
line and change children: <Widget>[...]
with this:
children: <Widget>[
// TODO: Handle overflowing labels (103)
Text(
product == null ? '' : product.name,
style: theme.textTheme.button,
softWrap: false,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
SizedBox(height: 4.0),
Text(
product == null ? '' : formatter.format(product.price),
style: theme.textTheme.caption,
),
// End new code
],
12. Would be good to center the labels, and align the text to the bottom of each card, instead of the bottom of each image.
Find the // TODO: Align labels to the bottom and center (103)
line
Remove or comment this line
crossAxisAlignment: CrossAxisAlignment.start,
And add the lines below:
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
Find the // TODO: Center items on the card (103)
line and remove or comment
crossAxisAlignment: CrossAxisAlignment.start,
And then add this one instead of it:
crossAxisAlignment: CrossAxisAlignment.center,
13. Press the “Hot Reload” or the “Build Projects” button. Your home screen should now look like this:
14. Everything looks not bad now. But don’t stop! Let’s beautify login form fields. Open the app.dart
file. Find the // TODO: Decorate the inputs (103)
line and add this part:
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(),
),
Inside thelogin.dart
file, remove or comment these lines: filled: true
:
15. Click the “Hot Reload” button or “Build Project” if it is active.
16. Would be nice to change the label color to be the same as color theme when clicked.
Inside the app.dart
, find // TODO: Decorate the inputs (103)
line and specify thefocusedBorder
under theinputDecorationTheme
:
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 2.0,
color: kShrineBrown900,
),
),
In login.dart
, add some new lines to TextField
inside InputDecoration()
constructor. Let’s do it for the Username field then we will repeat the same for the Password field (see the screenshot below):
labelStyle: TextStyle(color: Theme.of(context).accentColor),
17. In login.dart
we should init our FocusNodes
and unfocused label color at the top of our _LoginPageState
class (see the screenshot below):
final _unfocusedColor = Colors.grey[600];
final _usernameFocusNode = FocusNode();
final _passwordFocusNode = FocusNode();
18. Override initState
and add a listener for our FocusNodes
:
@override
void initState() {
super.initState();
_usernameFocusNode.addListener(() {
setState(() {
//Redraw so that the username label reflects the focus state
});
});
_passwordFocusNode.addListener(() {
setState(() {
//Redraw so that the password label reflects the focus state
});
});
}
19. Finally, add the focusNode:
property inside the TextField
widgets.
Let’s start from the Username field (see the screenshot below):
labelStyle: TextStyle(
color: _usernameFocusNode.hasFocus
? Theme.of(context).accentColor
: _unfocusedColor),
),
focusNode: _usernameFocusNode,
And now for the Password field:
labelStyle: TextStyle(
color: _passwordFocusNode.hasFocus
? Theme.of(context).accentColor
: _unfocusedColor),
),
focusNode: _passwordFocusNode,
20. Click the “Build Project” button or “Hot Reload”.
21. Want to know more? Let’s follow the beautiful manual from Material Flutter Team:
22. If you are still here and don’t get lost in the space, you will be a Great Flutter Programmer! Let’s admire our final result.
Awesome! You finished the 11th day of the agenda #30DaysOfFlutter!
Next “Code Party”: “30 Days Of Flutter” with FlutLab: Code Party 7
If you’ve stacked with some problems, visit FlutLab Widget Bay and find the source code of this challenge under the 30 Days Of Flutter category. You can just fork this Widget Bay project into your FlutLab account and play with it.
Good luck!