By Ümit Kara • September 21, 2022 • 8 mins read
Recently, I was working on web development. I build sites with pure PHP, Python and Django, pure JavaScript, Vue and Nuxt and PHP with Laravel. There are some points I didn't touch for now; like Angular and React or Express and Node. However, I hope to do so in the future.
After all of this, I thought moving into mobile development might be a reasonable move because the two are so closely related. As a starting point, I chose Flutter. Before Flutter, I wrote some basic Android applications in Java. I could dive into Java, but I was curious about Dart, so I began my Flutter journey.
Like every subject, the first thing you want to do is learn the basics. I started to research Dart and Flutter first and tried to find some helpful resources to learn the language and framework. The most comprehensive resource I could find was called Flutter Complete Reference by Alberto Miola (Here is the link to the site). The book does not only teach you Dart or Flutter, it also mentions the basics of both of them. Also, the writer talks about good practices for writing efficient and clean Dart and Flutter code. In this way you have a vision of how and when to use the given topic in a real situation.
Now I want to talk about some Dart basics. First, Dart is a very mature language. I worked with lots of languages and I can tell that Dart is not too difficult to learn. It is readable and easy to understand. It is also backed by a large community. When you face an obstacle, there is always help nearby. And it has a very large package library that you could use. For example I found out a web framework called Conduct that I want to try out instead of Python's Flask to develop some web applications.
Dart is developed and maintained by Google. It is intended to replace JavaScript. Therefore, some weaknesses of JavaScript have been eliminated in Dart.
Dart is strongly typed like TypeScript, unlike JavaScript. JavaScript's weakly typed feature is both a strength and a weakness at the same time. It is a strength because you don’t have to cast or convert types, however it could cause severe runtime troubles. The Dart team developed the language as strongly typed to prevent developers from running into runtime problems.
As like most other languages Dart has Numbers (integers and double precision floating points), Strings, Booleans, Lists (dynamic arrays), Sets and Maps (Associative array or dictionary).
There are several ways to define a variable. As in JavaScript, you can define variables with the var
keyword. As in most other strongly typed languages, you can declare a variable by putting <type>
before the variable name. Moreover you can declare a variable with the final
and const
keywords. Both of these keywords define an unchangeable variable, but in const you should initialize the variable value while declaring it.
In Dart, everything is an object, including classes. Declaring a class is similar to other OOP languages. The interesting part is you can use named constructors. Dart does not support function overloading, so to overload the constructor you create named constructors. The most simple example is creating an instance of the class from a JSON file. Lets say we have a user class, so it has a constructor like this:
class User() { final String username; final String firstname; User(this.username, this.firstname);}
In order to create a user object from JSON, we can add the following constructor:
...User.fromJSON(String jsonString){ ...}
Like other OOP languages there is inheritance. You can inherit from only one parent class with the extends
keyword. As you might already know, through inheritance, the class gets all functions and class variables from the parent class.
class Human() { final bool _mortal = true; bool isMortal() { return _mortal; }}class Socrates extends Human { ...}
Additionally, there are interfaces like C# and Java, but these are implicit. There is no keyword to define an interface directly, so you must create an interface with classes. Via the implements
keyword you can add one or more interfaces to a child class. Whenever you implement an interface, you have to implement all the methods of the parent interface.
class Person() { final String _name; Person(this._name); String greet(String who) => 'Hello, $who. I am $_name.';}class Impostor implements Person { String get _name => ''; String greet(String who) => 'Hi $who. Do you know who I am?';}
Furthermore, there are mixins in Dart. Mixins are also classes without any constructors. They only tie related functions together. Mixins are used when different types of classes share the same code. To avoid repeating yourself, you separate the shared code block into a mixin. Then you bind the mixin using the with
keyword to the related classes. Unlike the other two, mixins are not hierarchical.
Flutter is a mobile app SDK for building high-performance, high-fidelity apps for iOS and Android from a single code base using the Dart programming language. Like Dart, Flutter is also developed and maintained by Google. With Flutter you can develop high-quality native interfaces for iOS, Android, Web and Desktop rapidly. Again as like as Dart, Flutter is free and open source, and it has a big developer community behind it.
Flutter is a very fast SDK, compared to the other Cross-Platform frameworks. This is achieved by compiling to the native languages and owning the screen. If you own the screen, it means that everything you build with Flutter is displayed on-screen by Skia, Flutter's graphic engine. So you don't need to call native widgets and wait for them to show up or use a bridge.
Flutter looks beautiful thanks to its pre-designed Cupertino and Material Design themes and widgets. Everything is compatible with the selected look. It is possible for you to manipulate or completely change the look and feel of your app.
When we look at the development experience, Flutter is very productive thanks to its hot reload feature. When you are developing you don't need to compile the whole app when you make a small change, because Flutter detects it and reloads the changed field thanks to it's multi-tree widget rendering mechanics.
Now that we know a few things about Flutter, let's examine how it works.
Everything in Flutter is a widget. You build a whole app from widgets. Basically there are 2 types of widget, stateless and stateful. A small insider tip here, even the stateless widget is inherited from the stateful widget. Also there is a third type of widget called an inherited widget. As I mentioned previously you build the whole app using these 2 widgets.
Everything starts with an import statement. While working on a Flutter project everything that Flutter SDK provides comes with one handy import:
import 'package:flutter/material.dart';
With this import statement, we are able to define widgets, and add pre-built widgets to our app.
Flutter's widgets are immutable. So at runtime you can't respond to changes. Stateful widget solves this issue by creating a state class which lives outside of the widget. This state class is mutable so it can respond and react to changes. When a state changes you should alert the app about the change. Flutter traverses through the widget tree in this way and re-builds the changed widgets.
When there is no need for a state, you should choose the stateless widget. This is not because of performance, but rather because of code readability.
Example stateless widget:
class name extends StatelessWidget { const name({super.key}); @override Widget build(BuildContext context) { return Container(); }}
Example stateful widget:
class name extends StatefulWidget { const name({super.key}); @override State<name> createState() => _nameState();}class _nameState extends State<name> { @override Widget build(BuildContext context) { return Container(); }}
As you can see in these 2 examples, each widget returns a Container. A container is a wrapper widget, which is the equivalent of the div tag in HTML. For more information about widgets, you can check out Flutter's official widget catalog.
The main widget that we build our app on top of is called Scaffold. It is a special widget which gives us a lot of UI options. Essentially, it is a widget that has a solid background. But we can add app bar, app drawer, action button and more other widgets directly to it. It will handle placement, basic animation and show/hide behaviors for us.
The other essential widget that I previously mentioned is the AppBar. With it, you can place a screen title. It hosts the AppDrawer and any other action buttons you might have. And finally it shows a back button when you open a new screen.
The final widget I want to mention is the AppDrawer. As its name suggests, it is a side container. This container could act as a navigator for your app or show some extra information about the screen that it is on.
After walking through all of these basics, the only thing that is missing is building an app. There is one part we may want to examine though, that will ease our job while developing, called Firebase.
You might already know Firebase, but I want to mention it a little bit here before we start development. Firebase is also a Google product. It has free and paid tears. From a higher perspective, we could say that Firebase is a Backend as a Service (BaaS). A lot of future applications are possible with it, such as authentication, real-time database, storage, and hosting. We use it to store our data, with the Firebase Firestore. Firestore is a cloud NOSQL database. With it we can directly store our data on cloud and also directly access data that is newly created, updated or deleted. It solves a lot of problems otherwise we struggle to solve on our own. Additionally we will use the Firebase Authentication service for our apps sign in and sign up futures. With this service we could not only sign up a user with e-mail and password but also with other social platforms and even with mobile phone numbers. Finally with Cloud Messaging service we could create Push Notifications for our app in the twinkle of an eye.
Now that we have discussed all the things I wanted to mention here, let's move on to the development part. What I want to develop with Flutter and Firebase is a Twitter Clone. A clone that has timeline, profile, tagging, hashtags and the core functions that Twitter has. In the next chapter, we'll plan the app, then we will start to develop the Twitter clone app.