Flutter & Dart Flashcards
What is Flutter?
Open-source framework (tools, libraries, and conventions) developed by Google that supports building natively compiled, cross-platform(iOS, Android, MacOS, Linus, Windows, Web) applications from a single codebase.
Flutter uses Google’s Dart OOP language and provides a rich set of widgets for (and libraries???) for building beautiful and interactive user interfaces (UIs).
First released in December 2018.
Virtual Machine allows Hot Restart and Hot Reload - see changes without needing to restart the app - efficient development.
What is Dart?
Google’s open-source, OOP language released in 2011 with a strong, C-style syntax.
Is a statically-typed language - variable and function types are checked at compile-time instead of runtime.
Supports asynchronous programming with async, await, Futures, and Streams.
Has Dart DevTools for debugging and performance analysis.
Has several core libraries such as dart:io, dart:math, dart:convert.
Text Editor vs. Compiler vs. Software Development Kit
Text Editor: software tool for creating, editing, and manipulating text files, provides functionality for typing and formatting text. May include syntax highlighting, search and replace, and file management.
Compiler: software tool that translates source code into machine code or executable code that can be directly executed by a computer’s processor. It takes the source code, analyzes for syntax and semantic errors, and generates compiled code, which is usually stored in a separate file.
SDK: collection of software tools, libraries, documentation, and sample code to assist developers in creating software applications for a specific platform, framework, or programming language. Includes development tools, such as compilers and debuggers, libraries and APIs that provide pre-written code for common tasks.
Graphical User Interface vs. Command Line Interface
GUI: visual interface for users to interact with a computer system or software application using graphical elements such as icons, buttons, windows, and menus. Users can interact with the system or application by using a mouse, keyboard, or touch input.
CLI: text-based interface that allows users to interact with a computer system or software application by entering text-based commands or instructions. Users type commands, often with parameters or options, at a command prompt, and the system or application responds with text-based output.
Object Oriented Programming Core Concepts
Classes and Objects: Classes are blueprints or templates for objects, and objects are instances of classes. Classes define the structure and behavior of objects, while objects are specific instances created from those classes.
Encapsulation: Encapsulation is the process of hiding the internal details of an object and exposing only what is necessary. It involves using access modifiers (such as public, private, and protected) to control the visibility and accessibility of class members (i.e., variables and methods).
Inheritance: Inheritance allows one class (the child or subclass) to inherit properties and methods from another class (the parent or superclass). It promotes code reuse and allows for the creation of hierarchical relationships between classes.
Polymorphism: Polymorphism enables objects of different classes to be treated as if they were of the same class, providing a consistent interface for interacting with objects. It allows for method overriding, interfaces, and abstract classes.
Abstraction: Abstraction involves simplifying complex systems by creating abstract classes or interfaces that define common properties and behaviors, without providing implementation details. It allows for creating reusable and extensible code.
Dart Project Files
.gitignore: informs Git on which files it should NOT save to GitHub or other remote repository.
analysis_options.yaml: contains rules to help detect issues with code (aka: linting).
bin: the executable Dart code.
CHANGELOG.md: Markdown formatted list of updates to the project.
lib: short for “library,” contains all the .dart files (aka: “collection”).
pubspec.yaml: list of third-party packages for the project.
pubspec.lock: specifies precise versions of each package (aka: dependency) in the pubspec.yaml file.
README.md: place to describe the project and how to use it.
test: stores test files.
What is a Widget?
Basic building blocks of the UI (user interface) that describe the layout, appearance, and behavior of a certain part of the UI.
Is a class that represents a visual element, such as a button, text box, image, or container, which can be combined with other widgets to create a complete user interface.
Are organized in a tree-like structure, known as the widget tree or widget hierarchy, where parent widgets can contain child widgets, forming a parent-child relationship.
Two Fundamental Widgets
Stateless Widget: represents part of the UI that does not store any mutable (AKA: changeable) state. Is only rebuilt when a parent widget is rebuilt. Typically used for parts of the UI that do not need to change dynamically (continually able to change), such
Displaying static text, images, or icons…
Stateful Widget: a widget that can hold mutable state, meaning it can change its internal data over time. Used to create components in a Flutter application that need to maintain and update their internal state.
When created, it also creates a separate State Object that holds the mutable state. When the state changes, the framework rebuilds the widget.
For example, user input forms, animations, or data that changes dynamically…
Stateful Widget Lifecycle
- createState( ): creates the state object of a Stateful Widget, is where the mutable (changeable) state (information) is stored
* mounted (true): once called, the framework will associate the BuildContext (aka: insert into the widget tree)
to the Stateful widget by setting the mounted property as true - initState( ): called only once when the widget’s state object is created, best for http requests, subscribing to streams, or any object that could change the data of this widget.
- didChangeDependencies( ): called right after initState( ) or when an object that this widget depends on changes.
- build( ): required and will be called many times during the widget’s lifecycle.
- didUpdateWidget( ): called if the parent widget changes its configuration and has to rebuild the widget, framework gives you the old widget as an argument that you can use to compare it with the new widget, Flutter will call the build() method after it.
- setState( ): notifies the framework that the state of the object has changed (aka: “dirty”), the framework will then run the build( ) method to update / rebuild the widget.
- deactivate( ): called when the widget is removed from the widget tree.
- dispose( ): called when the state object is permanently removed from the widget tree
* mounted (false): since the state object is no longer in a tree, framework sets this property to false.
Common Display Widgets
Display content that fits within the available space and does not require scrolling. Typically used to display static or dynamic content that can be rendered within the visible area of the screen.
Text: Displays a short piece of text.
Image: Displays an image.
Container: A box that can contain other widgets and be styled with various properties.
Card: Represents a material design card. It can be used to display content in a card-like format.
ListTile: Represents a single fixed-height row that typically contains some text and an optional leading or trailing widget, commonly used in lists.
Common Scrollable Widgets
Display content that exceeds the available space and allows the user to scroll through the content. Typically used to display long lists, grids, or other types of content that do not fit entirely within the visible area of the screen.
ListView: Displays a scrolling, linear list of widgets.
GridView: Displays a scrolling, rectangular grid of widgets.
SingleChildScrollView: Provides a scrolling view for a single widget.
CustomScrollView: Allows for complex scrolling behaviors by combining multiple scrollable widgets.
What is a Widget Tree?
A hierarchical structure of widget objects that represents the user interface.
The root widget (typically a MaterialApp widget) has other widgets added as children to form the overall widget tree.
Build Method vs. BuildContext
BuildContext: represents the location of a widget within a widget tree, is used by the Flutter framework to both locate and manipulate widgets within an app.
Build Method: uses a Buildcontext object as a parameter in order to build a widget and its children widgets.
Dart Data Types
int: integer values without decimals
double: “floating-point” values with decimals
num: both integer and floating-point values (aka: integers with or without decimals)
String: sequence of characters
bool: boolean values that can only be “true” or “false”
List: an ordered collection of values, AKA: an array. can contain values of any data type, including other lists
Set: an unordered collection of unique values. cannot contain duplicate values
Map: an unordered collection of key-value pairs, where each key must be unique. AKA: dictionaries or hash maps
Type Annotation
Explicitly giving each variable, parameter, and function a data type.
Write the variable data type before the variable or constant name:
int myInteger = 1;
String name = 'Derrick';
Type Inference
Dart compiler’s ability to determine a variable’s data type without needing it specified by type annotation.
Provides additional information to the Dart compiler about the expected type of a value, and allows for static type checking during compilation rather than run time, which can catch type-related errors early in the development process.
var name = 'Derrick'; / / Dart will detect this is a String value
const vs final
Both are immutable (aka: values can’t be changed)
const: values that are determined by the Dart compiler BEFORE runtime and can’t be changed during compile time nor at runtime. Are more performant as values are embedded directly into the compiled code.
final: values that can ONLY be determined AFTER the program starts running and are mutable at runtime but can’t be changed after values are assigned.
Rule of Thumb: use const variables and only use final if the compiler complains.
var vs dynamic
var: a type inference keyword that asks Dart to recognize the data type when declared and Dart will INFER that data type thereafter.
dynamic: a Dart data type that allows a variable’s data type to be determined at runtime as opposed to compile-time and circumvents Dart’s Type Safety checks. Not recommended as it is prone to bug issues.
Type Safe
Dart’s ability to catch type-related errors during compile-time before the code is executed and at runtime. It prevents runtime errors due to incorrect and inconsistent data types within the code.
Static Type Checking: Dart’s static type checker analyzes code during compilation and checks that types are used correctly. Otherwise, it will throw an ERROR.
Strongly Typed: must declare the data type of each variable and function parameter as the compiler enforces the correctness of the types used throughout the program.
Runtime: type checks are done when the code begins to execute and throws EXCEPTIONS if there are type errors.
Dynamically-typed vs Statically-typed
Dynamically-typed: language where data types can change at runtime.
Statically-typed: language that does not allow data types to change - aka: type safety.
Dart is an Optionally-typed language that is statically-typed by default but can use the “dynamic” keyword to make it Dynamically-typed.
Sound Null Safety
A feature released in Dart that performs checks to make sure there are no null values where they aren’t expected, the goal is to control where, how, and when null values can be contained within the program.
All types are non-nullable by default and variables can’t contain null values unless you say they can by using the ‘?’ at the end of the data type annotation: String? name;
Null safety checks are performed at compile time to eliminate runtime errors and crashes.
Null values don’t allow the same operations to be performed on them as non-nullable values.
Accessing values: Non-nullable values can be accessed directly using their name, while nullable values require the use of the null-aware operator ‘?’ or the null coalescing operator ‘??’ to safely access their value - - - > (same requirement for checking if a nullable value is null OR to use a nullable value in an expression)
main( ) vs runApp( )
main( ): is the entry point of the app, called when the app is first launched, sets up the initial configuration of the app, typically used to create an instance of “MaterialApp” or “CupertinoApp.”
runApp( ): takes the given widget and makes it the root of the widget tree, is responsible for initializing and running the Flutter application.
Statement vs Expressions
Statement: code that tells the computer / compiler what to do.
print('Hello Dart'); - simple statement
if (something meets criteria) { - is a complex statement
// do something }
Expression: doesn’t do something, rather - it is something like a VALUE or a value that can be calculated.
Dart Keywords
class: Used to define a class, which is a blueprint for creating objects in object-oriented programming.
var: Used to declare a mutable (changeable) variable.
dynamic: data type that allows a variable’s data type to be determined at runtime as opposed to compile-time and circumvents Dart’s Type Safety checks.
final: Used to declare an immutable (unchangeable) variable.
const: Used to declare a compile-time constant value.
new: Used to create a new instance of an object.
this: Refers to the current instance of the class, typically used within class methods.
super: Refers to the superclass or parent class, used to call methods or access properties from the superclass.
static: Used to declare class-level members that are accessible without creating an instance of the class.
extends: Used to inherit properties and methods from a superclass in Dart’s class hierarchy.
implements: Used to define interfaces that a class should adhere to.
abstract: Used to declare abstract classes or methods, which cannot be instantiated but can be extended by other classes.
factory: Used to create objects in a different way than the default constructor.
get: Used to define a getter method, which allows accessing a class’s property like a variable.
set: Used to define a setter method, which allows modifying a class’s property like a variable.
async/await: Used for asynchronous programming in Dart, allowing for non-blocking execution of tasks.
Dart Operators
Order of Operations / Operator Precedence: Multiplication and Division are equal. Addition and Subtraction are equal but are lower than multiplication and division. Use parentheses if you want to perform addition or subtraction first.
Arithmetic Operators:
Add ( + ):
Subtract ( - ):
Multiply ( * ):
Divide ( / ):
Modulo Operator ( % ): divides two numbers and returns the REMAINDER
Assignment Operators:
( = ): assigns a value to a variable.
( + = ): adds a value to a variable and assigns the variable to the new value.
( - = ): subtracts a value to a variable and assigns the variable to the new value.
( * = ): multiples a value on a variable and assigns the variable to the new value.
( / = ): divides a value on a variable and assigns the variable to the new value.
( % = ): performs the modulo operation on a variable and assigns the new value.
Comparison Operators:
( == ): bool, checks for equality between two values. ( != ): bool, checks for inequality between two values. ( > ): bool, checks if a value is greater than another value. ( < ): bool, checks if a value is less than another value. ( >= ): bool, checks if a value is greater than or equal to another value. ( <= ): bool, checks if a value is less than or equal to another value.
Logical Operators:
( && ): returns true if both operands are true. ( || ): returns true if atleast one of the operands is true.
( ! operand1 ): performed on one operand and negates (reverses) the value of the operand.
Ternary Operator ( expression == true ? set to some value : else set to this value ): simplifies and If/Else Statement.
Classes
Combine data and functions inside of a single structure and are a blueprint or instructions that tells the system how to make an object. An object (aka: instance) is the actual data stored in the computer’s memory.
Functions inside of a class are called methods. Constructors are special class methods that are used to build class objects.
class User { String name; int age; User(this.name, this.age); } final user = User( ); / / calls the constructor and creates a User class object
Can access and assign values to class properties (aka: variables) via the dot operator.
Parameter vs. Argument: a parameter is the name and data type that is defined as an input to a function or constructor. An argument is the actual value passed into the function or constructor as an input when they are called.
Constructors
Are special class methods that create (aka: build) instances of a class.
Default - Dart provides by default and has no parameters or arguments. Also known as “implicit” or “unnamed” constructor.
Long-Form - uses a function body { } to initialize class properties: {this.id = id, this.name = name};
Short-Form - uses the THIS keyword to initialize class properties without a function body: User(this.id, this.name);
Named - constructor with a specific name defined by using the dot operator: User.fromJson( )
Factory - creates objects from a class without needing to create a new instance of the class, can also perform functionality before creating a class object. (.fromJson( ) is a factory constructor…)
Forwarding / Redirecting - helps prevent two or more locations initializing class properties by passing in initial values: User.anonymous( ) : this(0, ‘anonymous’);
Constructor Parameters: Can be optional, named, and required:
Optional: enclose parameters inside of square brackets [ ]
Optional & Named: enclose parameters inside of curly brackets { } within the constructor definition
Named & Required: enclose parameters within curly brackets { } within the constructor definition and use the keyword: required
Enums
Define a fixed set of constant values for a particular variable.
enum Makes { Toyota, Honda, Nissan } void main( ) { Makes myMake = Makes.Toyota; / / assigns the enum value print(myMake); / / outputs Makes.Toyota }
Mixins
Allows the reuse of code in multiple classes without requiring each class to inherit from a common superclass.
Use the with keyword after a class name to allow access to the mixin code from within another class.
Example:
mixin Vehicle { String make; String model; void startEngine( ) { print(‘Starting engine of $make $model’); } class Car with Vehicle { Car(this.make, this.model); void drive( ) { print(‘Driving $make $model’);