DEV Community

Colton Ehrman
Colton Ehrman

Posted on • Updated on

Learning Journey - Flutter

I've been wanting to start documenting what I am learning and write down more content lately. This seems like the perfect opportunity to do so!

My friend introduced me to Flutter after showing me an app that he put together in several months. After checking out how slick the app was, I was intrigued. I had already made a couple of apps using Swift, and React Native, but nothing that looked as good as this one. (of course maybe he's just better at making apps than I am)

Several weeks have passed, I had looked into a couple of articles about Flutter and skimmed through the official docs but hadn't really decided to take the dive to start learning it. After having begged me to start learning flutter and proposing to work on a project together with me involving flutter and machine learning, my friend's persistence finally paid off.

A couple of days ago, I went ahead and bought two courses on Udemy, one by Stephen Grider and another by Maximilian Schwarzmüller. My friend recommended that I get a course by Dr. Angela Yu, but my stubbornness chose to pick something else.

Summary Of The Courses I Got

by Stephen Grider
In my opinion, from past experience with his courses, Stephen is really good at explaining how something works. Instead of just teaching you how to do something, he teaches you why it works and goes deeper into the topic to give you a better understanding.

What I Learned So Far

Dart Sections

Flutter Sections

Dart

Background

What is Dart & Flutter?

Dart is an Object-Oriented language, with syntax similar to JavaScript, and can optionally be transpiled into JavaScript code. Dart by itself, is just a programming language. Flutter is the framework that is used by Dart in order to build applications that run on Android and iOS.
Dart + Flutter = Cross-Platform App

Dart Overview
  • Object-Oriented language
  • Statically typed language
  • C-Style syntax
  • Multiple Runtime Environments
    • Mobile Devices - Compiled to Machine Code
    • Browser - Transpiled to JavaScript
    • Command Line - Dart VM
Online Dart Compiler/Playground

DartPad

First Dart Program

// Function declaration
String myName() {
  return 'Colton Ehrman';
}

// Main function where program starts execution
void main() {
  // variable initialization
  String name = myName();
  // print something out
  print('My name is $name');
}

Function Syntax

// Function Declaration / Definition
[return Type] [function name]([parameters]) { // [parameters] is optional
  [code] // [code] is any number expressions inside the curly braces
}

// Examples
String myName() {
  return 'Colton Ehrman';
}
// [return Type] is String
// [function name] is myName
// [parameters] is not provided - optional

void printName(String name) {
  print('My name is $name');
}
// [return Type] is void
// [function name] is printName
// [parameters] is a single variable
//   String name

Variable Syntax

When using var as the [Type] in Dart, the type is inferred. Although types are mandatory, type annotations are optional because of type inference. - Dart Type System

// Learn more on Dart Types
// https://dart.dev/guides/language/sound-dart

// Variable Declaration
[Type] [variable name];

// Examples
String name;
// [Type] is String
// [variable name] is name

var anotherName;
// [Type] is var
// [variable name] is anotherName

Initializing Variables

When initializing a variable, you must match the [Type] of the variable with the [Type] of the value you are assigning to the variable. In cases where you do not explicitly define the [Type] of the variable, Dart will use Type inference to determine the type. Once the [Type] of a variable is set, you cannot assign a value of a different [Type] to that variable

String name = 'Colton Ehrman';
// variable [name] of [Type] String is being assigned
// a value of 'Colton Ehrman' which is [Type] String

name = 'Colton J. Ehrman';
// variable [name] is being re-assigned
// a new value of 'Colton J. Ehrman' which is [Type] String

// Error!
name = 123;
// invalid assignment of [Type] int to
// variable [name] with [Type] String

String Interpolation

How Dart variables and/or expressions are interpolated - insert something of a different nature into something else - into Strings.

Strings in Dart are surrounded by either double quotes "[String]" or single quotes '[String]' (single quotes seem to be the most common convention).

To interpolate something into a String, you prefix it with a dollar sign $. If you are interpolating an expression, you will wrap the expression inside of curly braces which follow the dollar sign ${[expression]}.
You may always use the curly brace expression, but conventionally it is only used when required.

String firstName = 'Colton';
String lastName = 'Ehrman';
String fullName = '$firstName $lastName'; // interpolated value
// fullName will be the String 'Colton Ehrman'

int yearBorn = 1995;
int currentYear = 2020;
String ageText = 'I am ${currentYear - yearBorn} years old!';
// interpolating an expression inside of a String
// ageText will be 'I am 25 years old!'
Weird interpolation example's to watch out for
String firstName = 'Colton';

// trying to interpolate Object property into string
String weirdResult = 'My name is $firstName.length characters.';
// weirdResult will be 'My name is Colton.length characters.'

String properResult = 'My name is ${firstName.length} characters.';
// properResult == 'My name is 6 characters long.'

Without the curly braces in the interpolation, Dart will only interpolate up to a valid variable name, anything else that follows will be treated as a String.

Creating a Class

// class definition
class [class Name] {
  // body of class
  // the class can consist of these things
  // the order does not matter
  [constructors]
  [properties]
  [methods]
}

// Example
class Person {
  String firstName; // property
  String lastName;  // property

  // method
  String fullName() {
    return '$firstName $lastName';
  }
}

In the example, we are defining a class named Person, which consists of two properties, firstName and lastName, and a single method named fullName.

Creating an Object

With our previous Class Person, we will create some Objects.

// declare variable of [Type] Person
Person me;

// assign new instance of Person to variable
me = new Person();

// assign values to object properties
me.firstName = 'Colton';
me.lastName = 'Ehrman';

// calling object methods
String myFullName = me.fullName();

// Error!
me.eyeColor = 'brown';
// the Person class does not have a property of 'eyeColor'
// so this will cause an error in Dart

You can create new instances of a Class by calling it like a function with the new keyword in front of it (new [Class name]() | new Person()).
The new keyword is actually optional and you can create an instance of a Class without it.

To access properties and methods of an object you use dot-notation ([object].[property|method]).

Class Constructors

class Person {
  // constructor
  // must named the same name as Class name
  // can have any number of parameters
  Person(String firstName, String lastName) {
    this.firstName = firstName; // assigning property
    this.lastName = lastName;   // assigning property
  }

  String firstName;
  String lastName;
}

A Class's constructor must be named the same as the Class's name. If the constructor takes parameters that have the same name as properties of the class, you must differentiate them by using the this keyword in front of the properties of the Class.

this keyword is not required when using properties/methods of a Class, unless in a context where the reference would be ambiguous.

With a constructor now, when you instantiate Objects of a Class, the appropriate constructor will be called.

Person me;

// will call the constructor that we defined earlier
me = Person('Colton', 'Ehrman'); // the 'new' keyword is not required
// 'me' Object will be created with
// 'firstName' and 'lastName' properties already set
Special Constructor

In Dart, you can easily create common constructors, like the one we made earlier, using a special syntax.

Let's take the previous constructor and simplify it using the new syntax.

class Person {
  // special constructor
  // parameters must be prefixed with 'this.'
  // parameters must match class properties
  Person(this.firstName, this.lastName);

  String firstName;
  String lastName;
}

With this new syntax, Dart will automagically understand what you want and do it for you. It is the same as the previous constructor we made.

Just remember: each parameter must be prefixed with this. AND match a property that exists within the Class

Flutter

Widgets

Widgets are the building blocks of flutter. Practically everything you do will be in the form of a Widget. The flutter framework provides tons of built-in Widgets to get started with. You will use these along with building your own custom Widgets.

Common Widgets

As you start building with the Flutter framework, you will become accustomed to common Widgets that you will use.

Such as

These are just a few of the most common Widgets, there are many more that you will see as well.

ListView

ListView is a common Widget used when building a list of Widgets in your App, that the user can scroll through. Think, social media feeds, probably the most common ListView we are familiar with.

You typically will be creating a custom Widget that utilizes the ListView.

There are two common constructors that you can use when building a ListView. One is the build all at once constructor (ListView()) and the other building on-demand constructor (ListView.builder()).

You will want to decide which one best suits your needs. If you know the list is going to contain a lot of elements and potentially take a while to build all at once, you probably want to use the ListView.builder(). Otherwise, the main constructor should do the trick.

Just keep in mind what kind of list you are trying to build and how the ListView will affect the performance of your app.

To Be Continued...

Top comments (0)