-
Notifications
You must be signed in to change notification settings - Fork 0
Hello Flutter
Now is an incredible time to be a mobile developer. Smartphones, tablets, and smart watches have become an important part of our lives, and Android and iOS keep getting better and adding new features at each new release. Great new frameworks help developers build apps faster and more reliably, and Flutter is, of course, one of those frameworks.
I'm really glad to have the chance to show you the basics of Flutter, which I hope you'll agree with me by the end of this tutorial, is an incredible tool. Here's what we'll do during this tutorial. In this chapter, we'll introduce Flutter in the context of mobile development and see how it can help you build your next great app. You'll also write your first hello world app and we'll try to make it a bit more interesting than simply writing hello world on a screen.
The next chapter is all about widgets. They are the main building blocks in Flutter. You'll see some of the most common widgets that are used in Flutter and how you can build complex user interfaces by using widgets hierarchically.
Then we'll talk about state in Flutter apps. Maintaining state is a challenge that every mobile app must face and stateful widgets will help us with that. This is how we'll achieve interactivity.
After that, we'll write our first real world app. We'll pass data through screens and read and write data from a database.
Finally, you'll get a brief introduction to gestures and animations, which can help your app really stand out from your competitors.
By the end of this tutorial, you'll have a solid understanding of how Flutter works and how you can use it to build great apps. Before moving to our hello world app, there are a few questions to answer and the first one is why Flutter?
We could write hundreds of pages on the different ways to develop for mobile platforms. To make it really brief and simplifying a great deal, you have three major ways to develop for mobile, native, hybrid, and web.
Native means that you use the native official tools, and today, that means Android Studio with Java, Kotlin coding for Android and XCode with Swift of Objective-C for iOS.
Android Studio and XCode with their supported languages are both great tools, tried and tested. They get new features as soon as they are available. They build fast and efficient apps using all the device capabilities natively, but they share one major disadvantage.
If you want to build an app for both iOS and Android, you need to create and maintain two apps, one for each platform, and you need to know at least two languages.
At the other end of the spectrum, you have web apps. You access them from a browser and web apps lets you share the same code for both mobile and web development. This is great for developers who use HTML, CSS, and JavaScript. Only one code for any system, easy to use, easy to implement with one major flow. You cannot reach the device more advanced features and the user may feel your app isn't really an app. It's just a website really in the form of an app. Even if there are tools to overcome some, but not all of the limitations right now.
And there's a third way. Tools like Xamarin, Cordova, Ionic, Reactive Native, just to name a few, those are called hybrid. Each of them has some advantages and disadvantages, but all these frameworks make you build your apps with a single code base for mobile.
They generally use some form of JavaScript, except for Xamarin that uses C#.The problem with most of them is they need a bridge between your code and the mobile operating system and some of them have performances that are well below the level of native apps. Not only that, but in some cases, the complexity of using several third-party libraries and components with their compatibility issues can make the developer life a nightmare. Believe me when I say that I've been there.
Where does Flutter fall then? In the hybrid category with a couple of features that Google believes can make the difference.
The first one is that Flutter compiles to native for excellent performance. Actually, Flutter has two different compilation models. Just-in-time compilation where code is recompiled in real time allowing hard reload. This means that when we develop, we see the changes in real time with no need to recompile. You write the code and you see the results immediately on your device or emulator. Then you have ahead of time compilation. Code is compiled to native arm code for great performance on any device. This is what you'll use when you're ready for production.
Flutter has been created to give developers a fast development framework, and to users, a great engaging and fast experience. And of course, you'll have a single code base for both iOS and Android. Another difference from other hybrid frameworks is that with Flutter you don't have bridges between your code and the device and this is another feature that can make Flutter stand out from some of its competitors.
Actually, Flutter is a very young framework. It was announced at Google I/O in May 2017 with an alpha toolkit and at Google I/O 2018, the third beta was announced. So now, according to Google, Flutter is ready for production apps and this is the version we'll be using in this tutorial.
Even if it's production ready, there may be some major changes in the future. In case this happens, I'd keep the tutorial and the code updated on GitHub. Have a look at the link below to get to the project page.
When you develop for Flutter, use a language called Dart
. It's a strongly-typed object-oriented programming language developed by Google. If you don't know Dart, don't worry. If you are familiar with C#, or Java, or Swift, or TypeScript, or even JavaScript, you'll have no problems at all with Dart.
You'll see that it's intuitive and easy to learn. And even though this is not a Dart
tutorial, you'll get enough elements to get started with Dart as well.
So what do you need to know before starting this tutorial? Well you need to know any object-oriented programming language. If you understand variables, control flow, inheritance, classes, and objects, you're good to go. And what do you need to have?
You can use a Windows PC, a Mac, or a Linux box as we'll be using Visual Studio Code, which is open source and compatible with all three operating systems. You'll also need an Android device. If you are on a Mac, you can also choose an iOS device or you can use an emulator. I'll give you the links on how to install those in the next lesson. For the examples and demos during the tutorial, I'll be using the Windows PC with an Android emulator, but feel free to use your favorite configuration.
Also, if you want to use Android Studio or IntelliJ IDEA instead of Visual Studio Code, you can definitely do that, even though some shortcuts will be different. Okay. Let's do part of the installation together next.
We'll now see how to install Flutter on a PC. The process for a Mac or Linux is very similar. In this tutorial, we'll be using Visual Studio Code, which is one of the supported editors in Flutter. This is because it's lightweight fast, easy to set up, and chances are you might have used it for other projects before. If you already use Android Studio or IntelliJ IDEA, you're welcome to use one of those as well, just make sure the version you are using supports Flutter and you installed the required plugins. You'll find the installation guide at the link you seehere. Actually, you could use any text editor combined with a Flutter command-line tools or CLI, but your life will be much easier if you use the plugins that are available for Visual Studio Code, Android Studio, or IntelliJ IDEA as you get code completion and debug features.
At this point, you should have an Android device available or an iOS device if you are on a Mac. Alternatively, you can install an emulator or simulator. Whatever setup you'll choose, there is one thing you'll need to do in any case, installing the Flutter SDK. You can find it at the address you see on the link here.
This is the official Flutter website, and there, you'll also find the official guide, several demos and tutorials, and almost everything else related to Flutter. Now just click on the Get Started button and then choose your operating system. Then follow the instructions you find there. The page you see when you installed your own project may be slightly different, but it's a very straightforward process, so I leave it to you to complete the SDK installation on your machine. Just pause the video now, and when you're finished,we'll install Visual Studio Code and its plugins. If you'll follow me with Visual Studio Code, let's see how to install and test that everything's working. What we'll do here is install VsCode, install the Flutter plugin that also includes start, and test that everything is working fine. Let's get to the link you see on the slide. And click on the operating system we are using. As I'm using Windows, I'll select that. We'll save the installation file and execute it as soon as the download process has finished. If you already have Visual Studio Code, make sure you update to the last version. The installation process is really straightforward, so we'll just follow the installation wizard until the end. Just make sure you leave the PATH option selected as this will simplify your life in the future. Once we have finished installing Visual Studio Code, one setting I suggest you check is the automatic saving. This is very useful, especially with hot reload. If this setting is on, you never have to save your files anymore. They get saved in real time while you type, great time saver for me. If you have a fairly powerful machine, this will go smoothly. But if you notice that Visual Studio Code is slowing down your system, then just put this off, but remember to save your files manually.
Okay, let's install the Flutter plugin. From the Extension Manager, let's type dart and press Enter. The first result should be the Dart code extension. Let's click install and after a few seconds, we'll be ready to use Flutter on Visual Studio Code. Remember to restart the editor and we are ready to go. It's that easy. Now let's press Ctrl+Shift+P
or Cmd+Shift+P
on a Mac to see the command pullout. You can also press View command pullout. From there, type doctor, and select the Flutter: Run Flutter Doctor action. Then review the output in the Output pane for any issues. So if everything went okay, in the output section, we can see that everything worked.
We are now ready to create our first tab. You have two choices when creating a new project. You can do it from the command line or directly from the editor. For this app, we'll do it from Visual Studio Code.
- Open the Command pull out. You can do that with
Ctrl+Shift+P
orCmd+Shift+P
on a Mac, type flutter in the box, then select the Flutter: New Project command, and press Enter. You now need to enter the project's name. Let's type hello_flutter. The rule for naming apps is lowercase with underscores. Try to create an app with uppercase and you'll see an error. Then select a project location. I create a new hello_flutter folder for our project. After choosing the folder, our project will be created. You'll see that you are inside the lib, main.dart file. This is where we'll write all our code. Let's remove the widget_test.dart file in the test folder. We won't need it in this project.
Then let's get back to the main.dart file and delete all the code we find here.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
We'll be writing our hello_flutter app from scratch.
First, we need to import the material.dart package
.
So we'll just type import package:flutter/material.dart
. This package contains widgets that implement material design. Material design is a design language developed by Google and it contains several widgets that we'll use now and in the following chapters. A package is simply a library of functions. The library we are importing contains widgets, and in particular, material widgets.
Next, we'll create a method called main
. This is the entry point of a Flutter app. Inside here, we'll call runApp()
. The runApp method inflates a widget and attaches it to the screen, which basically means that runApp will show on the screen the widget we put inside the method.
Center()
is a container widget that centers its content onto the screen. So whatever you put inside the center widget will be centered both horizontally and vertically.
child
is a property that allows us to nest widgets inside other widgets. Text is simply a text box. For the text of our text widget, let's type "Hello Flutter". Notice that we need to specify a textDirection. Ltr means left to right. So in this case, we use the child property of the center widget to put a text widget in the center of the screen.
import 'package:flutter/material.dart';
void main(){
runApp(
Center(child: Text(
"Hello Flutter!",
textDirection: TextDirection.ltr,
), )
);
}
Congratulations. You have written your first hello world app. Let's run this and see how it looks.
Remember to connect your device or open your emulator or simulator before running this code. So let's get to Debug, and from there, click on the open launch.json button.
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Flutter",
"request": "launch",
"type": "dart"
}
]
}
You'll need to do this only the first time. Then let's click on the Start Debugging button. And as you can see, our app shows a new screen. Okay, let's briefly recap what you should remember from this first hello world app.
- The
main
method is the entry point of your Flutter app. It's from here that you call therunApp()
method to show a widget on the screen of your device. Everything in Flutter is a widget, soCenter
andText
are widgets. The Center widget centers another widget both horizontally and vertically and Text writes some text. Remember to specify a text direction when you use text and ltr means left to right. The new keyword is now optional in Flutter.
Now let's face it, this is isn't the most beautiful app you have ever seen, right. Well the good news is that we can make our user interface a bit better very simply and that's what we'll do in the next lesson.
As we can use material design in our Flutter app, let's make the user interface a bit nicer. First, let's introduce the MaterialApp
widget. This gives you the opportunity to give a title to your app. This is what the operating system will see as the title when you scroll through your apps. Let's type Hello Flutter
App for the title property. A MaterialApp widget has a home property. Into that, we can insert a Material widget. A material has a color property so that we can choose a color, in this case, deep purple. Colors
contains several color constants. The material widget also has a child property to nest other widgets. So let's create a child property, and into that, let's select, cut, and paste the center
widget we created previously. Let's also beautify our code a little bit. There's a handy shortcut that is Shift+Alt+F
in Windows or Shit+Option+F
in Mac. Okay, that's better. Let's have a look at our app right now. You can see that now the background color is a beautiful deep purple. This is because of the color property of the material widget, and if we scroll the apps on our device, you can see that the title is what we specified in the title property of the MaterialApp widget. So far, so good, but we can certainly do better. For example, to the text widget, we can add a style. This will take a TextStyle with some properties. Let's choose a color again. Let's say white and a fontSize. Let's make it 36. We need to specify the .0 as the fontSize property requires a double. Let's have a look at our app. You can see that the colors and size of Hello Flutter have changed. Let's get back to our code. We can remove the new
keyword as it's optional in Flutter since better version 3. It's good you can recognize both ways to use widgets, but I personally prefer the shorter version. We'll now add a Scaffold
widget. This allows us to create an application bar. So in the AppBar
property, we place an AppBar widget that will contain the text we want to show in the application bar. Let's say that the Text
will be Title in App Bar. Let's create a body property under the title, and here, we'll move our material widget into the body property of the scaffold. So we use two properties of the scaffold widget, AppBar
that contains an application bar and body that contains the main content of the screen or page. And let's see how it looks right now. Now our app will look more like an app. As you can see, we have an app bar with our title, and below that, the body of the scaffold
widget. Okay, you get it. We could add elements here in a hierarchical order and we could write a full app like this into the runapp
method of the main function.
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: "Hello Flutter App",
home: Scaffold(
appBar: AppBar(
title: Text("Title in App Bar"),
),
body: Material(
color: Colors.deepPurple,
child: Center(
child: Text(
"Hello Flutter!",
textDirection: TextDirection.ltr,
style: TextStyle(color: Colors.white, fontSize: 36.0),
),
),
),
),
));
}
But I'm sure you'll agree with me that this wouldn't be a great idea, especially if the app keeps growing. Generally speaking, we want to leave the main method as simple as possible. Let's see how we can achieve that in the next lesson.
In this lesson, we'll introduce Dart. Dart is an object-oriented programming language. Widgets are objects and objects are instances of classes. Of course, we can also create our own classes. So let's create a class and call it HelloFlutterApp. In classes, you should use pascal case, also known as upper camelCase, meaning that each word in the class name, including the first one, begins with an uppercase letter. This will extend StatelessWidget. What this means is that our class will inherit from the StatelessWidget class, which is a generic widget that never needs to change. So StatelessWidget is the super class and HelloFlutterApp is the subclass. This is how you implement inheritance in Dart and Flutter. You can see that Visual Studio Code is telling us that something's wrong. That's because we need to override the build method. In order to do that, you can click on the bulb for the quick fix options. This will create the build method for us. Now we need to return the material app we have created above. So let's cut the code and paste it here. Inside the runApp method, we create a new instance of our HelloFlutterApp class.
import 'package:flutter/material.dart';
void main() {
runApp(new HelloFlutterApp());
}
class HelloFlutterApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Hello Flutter App",
home: Scaffold(
appBar: AppBar(
title: Text("Title in App Bar"),
),
body: Material(
color: Colors.deepPurple,
child: Center(
child: Text(
"Hello Flutter!",
textDirection: TextDirection.ltr,
style: TextStyle(color: Colors.white, fontSize: 36.0),
),
),
),
),
);
}
}
If we try this out, we can see that it's still working. We can also change the main method with an arrow
operator. Some developers call it fat arrow
operator. This is to further simplify the function. It is a short hand used for one-line functions or methods.
import 'package:flutter/material.dart';
void main() {
runApp(new HelloFlutterApp());
}
class HelloFlutterApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Hello Flutter App",
home: Scaffold(
appBar: AppBar(
title: Text("Title in App Bar"),
),
body: Material(
color: Colors.deepPurple,
child: Center(
child: Text(
"Hello Flutter!",
textDirection: TextDirection.ltr,
style: TextStyle(color: Colors.white, fontSize: 36.0),
),
),
),
),
);
}
}
According to the Google specification, consider using the fat arrow for short functions and methods, but only use it when everything including the function declaration fits on a single line.
Fat Arrow
void main() => runApp(new HelloWorldApp());
vs
void main()
{
runApp(
new HelloWorldApp();
);
}
So the two ways to write the main method that you see on the slide are exactly the same. Other languages have the same syntax, but if it's the first time you see it, you should be able to recognize that as it's pretty common in the language documentation.
Okay, we all know that it's a good idea to write an app that is as modularized as possible. So let's say that in an app that is bigger than this one, we want to put a class in a new file.
So for each screen or page of the app, we create a new file. We can achieve this by creating a new folder in the lib directory, let's call it screens
, and from there, we'll create a new file called home.dart
, and we'll create a class copying the code we have written in the main.dart
file. Let's import the material.dart package. Then let's create a class called Home that extends StatelessWidget, and in order to see the quick fix options, we can just press Ctrl+. or Cmd+. on a Mac so we can have Visual Studio Code create the build method for us, and here, we'll return the material widget that is currently in the body of the scaffold object in the main.dart file.
import 'package:flutter/material.dart';
class home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(
color: Colors.deepPurple,
child: Center(
child: Text(
"Hello Flutter!",
textDirection: TextDirection.ltr,
style: TextStyle(color: Colors.white, fontSize: 36.0),
),
),
);
}
}
In the main.dart file, we now need to import our home.dart file from the Screens folder. In the body of the scaffold, we'll put a home object. You will see that this is a very common pattern in writing Flutter apps.
import 'package:flutter/material.dart';
import './screens/home.dart';
void main() => runApp(new HelloFlutterApp());
class HelloFlutterApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Hello Flutter App",
home: Scaffold(
appBar: AppBar(
title: Text("Title in App Bar"),
),
body: home(),
),
);
}
}
Okay, if we try it out, we can see that everything works. Notice the debug mode text on the screen. I find it awful, so let's remove it. And we can do it with a debugShowCheckedModeBanner
property and setting it to false
.
import 'package:flutter/material.dart';
import './screens/home.dart';
void main() => runApp(new HelloFlutterApp());
class HelloFlutterApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
...
As you can see, the debug text has disappeared. Okay, let's recap the widgets we've seen so far.
- A MaterialApp is from the container of the other widgets in our apps. We've seen that it contains a title and a body, but we'll see during this course that it's also useful for navigation and routing.
- A Material is a widget that can have properties like color to give a background to our app. It can also have shape, shadow, elevation, and other properties that change the way it behaves.
- Center is a container that centers its content.
- We use Scaffold to show the app bar where we put the title of our app, but it's also used for floating action buttons, drawers, snack bars, and other material widgets. If you don't know what I'm talking about, don't worry, we'll see all of those during the course.
- AppBar is a tool bar that we use to give a title to our app.
- Text, well, shows text.
Okay, up to now, we have only designed some user interface. Now you might be wondering how can you add some logic to a flutter app. Let's say we want to write an if statement or a while loop or some other logic, well that's what we'll do next.
Now we are ready to add some logic to our Flutter app. The first question you might have is where. Where can you add say a function?
Well if everything is a widget and a widget is really an instance of a class, we can certainly add a function to a class, right.
So in our Home class, let's set a method that will return a string called sayHello. This won't take any parameter, but will return a string. So let's create a string, we'll call it hello, and for now, let's say that we'll return it at the end of this function.
A couple of words about Dart. Dart is strongly typed
, so if you try to put a number into this string, you'll get an error. At the same time, it's also very flexible so we could make a declaration with var
instead of string. In this case, the variable can contain anything. So you could put a string into it like hello, you could put a number like 8 and it would work fine.
I know this may appeal to many developers, especially if they come from JavaScript, but I would suggest not doing this unless really necessary and make the language help us by using strong types as much as possible.
Now about numbers. There is a type called num
that can contain both decimals and integers. So let's create a number called myNum, we can put an integer like 42 or a decimal like 3.14. If we want to be more specific, we can int
, which will work only for integers, or double
, which will work only for doubles.
...
String sayHello() {
String hello;
hello = "hello";
//var hello = "hello";
//var hello = 8 ;
//num myNum = 42;
// int myNum = 10;
//num myNum = 3.14;
//double myNum = 3.14;
return hello;
}
...
So this is how variables work in Dart. You have to create them, they must have a type, even though you can choose to use var if you want to create a generic variable and you have two types of number, integer
and double
. If you want to use both of them, you can just use num
, which is valid for both. You also have the DateTime
type.
Let's create a DateTime
, we'll call it now, which will call the now method of a new DateTime object. What we want to do now is make our hello flutter app a bit more interesting by choosing what to say to our user based on the time of the day. So if it's between 12, we'll say good morning. If it's between 12 and 18, we'll say good afternoon, and after 18, we'll say good evening. We can get the hour by reading the hour property of our now DateTime variable.
Like in any other language, you have the if statement in Dart and it works exactly as you would expect. So let's write that if the hour is less than 12, hello will equal to Good Morning. Else, if hour is less than 18, hello will be Good Afternoon. Else, hello will be Good Evening.
...
String sayHello() {
String hello;
DateTime now = new DateTime.now();
int hour = now.hour;
if (hour < 12) {
hello = "Good Morning";
} else if (hour < 18) {
hello = "Good Afternoon";
} else {
hello = "Good Morning";
}
return hello;
}
...
One last step before trying our app. We need to call the sayHello function from the text widget in the build method. So let's delete the HelloFlutter string and call the sayHello function.
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(
color: Colors.deepPurple,
child: Center(
child: Text(
sayHello(),
textDirection: TextDirection.ltr,
style: TextStyle(color: Colors.white, fontSize: 36.0),
),
),
);
}
String sayHello() {
String hello;
DateTime now = new DateTime.now();
int hour = now.hour;
if (hour < 12) {
hello = "Good Morning";
} else if (hour < 18) {
hello = "Good Afternoon";
} else {
hello = "Good Morning";
}
return hello;
}
}
Let's try these out and it works as expected. Now I don't know the time for you right now, but I see Good Morning here because it's before 12. If you don't see Good Morning, try again tomorrow to see if it's really working. I'm just joking.
Make sure you do not stop the app so we can see hot reloading
in action. So with the app still running, let's make a few changes to our code. Let's set the minutes as well so that I can show you something else. Let's say we want to tell our user the time before saying hello. So let's declare an int called minute, which as you can guess will be now.minute. Now we have a problem. If the minutes are less than 10, we want to put a 0 before the number. So let's say it's now 8 minutes passed 10. I want to show the user 10:08 and not 10:8. In order to do that, we use a Ternary operator. Let's declare a minute string that will check if minute is less than 10. If this is true, we'll assign minutes the value of 0 + minute converted to a string with a toString method. Otherwise, we'll just assign minute also converted into a string. Now let's return the time to our user. So we'll write It's now + hour.toString + a colon + minutes, then we'll create a new line and we'll write our hello string. To see if it's working, let's just have a look at our device and you can see that all the changes were applied without any action. We didn't have to recompile, we didn't have to update anything.
Great, isn't it. Okay, let's recap what we've done so far.
- We've seen why Flutter might be a great framework to use for your apps with its compiling features, the single code base for both Android and iOS.
- We've seen that Flutter apps are widgets and we've seen several widgets in our HelloWorld app. The entry point of a Flutter app is the main method that contains a runApp method, and inside the runApp method, we put a widget, which is usually a materialApp.
- We've seen that you modify the user interface with styles directly in Dart and you can add your own logic into widgets.
- We've also seen a little bit of Dart syntax, and I hope that you've found Dart familiar in a way and intuitive.
Okay, that's it for this module. In the next module, we'll see several other widgets that will be useful to build a real-world app. Thanks for following me, and I'll see you there.