3. Flutter Essentials | FlutterFlow University Expert Training

4.02k views4090 WordsCopy TextShare
FlutterFlow
Unlocking Flutter Essentials: A Comprehensive Guide to Flutter Development Welcome back to FlutterF...
Video Transcript:
Welcome to the Flutter Essentials module. Flutter is the technology behind FlutterFlow. The output of any Flutter flow project is Flutter code.
One of the examples of Flutter apps is FlutterFlow itself, which is built with Flutter. Therefore, knowing Flutter can help you expand your app even further, with no limit. You can add more features to your app by writing custom code.
For example. Whether you are a web developer, a native developer, or a backend developer. We will make Flutter concepts easy to understand.
Here is what you will learn in this module. First, we're going to start with the basics of Dart, the language behind Flutter. Then we go through the basics of Flutter and why they are a game changer.
Then we're going to review the Flutter architecture and how it's built. Then we're going to go through the widget centric approach that is the core to Flutter. Then we're going to review the project structure in any Flutter application.
And then, we're going to follow the Flutter build toolchain, including JIT and AoT compilation. Then you will see how you can use packages and plugins and modules and and what are the differences between them. And then we will go through pub.
dev and learning the basics of how to use packages from pub. dev. And at the end of this module we're going to have a simple comparison of Flutter for web developers, native mobile developers and backend developers.
And I will provide more resources for you to go through and learn more about Flutter with the previous knowledge that you already have. By end of this module, you will have a good foundation in Flutter and know how it works and how you can leverage it to build your apps in FlutterFlow. I cannot wait.
Let's get started. Let's start by understanding what is a programming language. A programming language is a set of instructions that tells a computer what to do.
Developers use it to write code that creates software applications. Like human languages, programming languages have their own syntax, rules and semantics. Meaning - while programming languages enable us to write the logic and functionality of our application, we also need tools to design and build the user interfaces that users interact with.
This is where a UI framework comes in. The UI framework is a tool that helps developer build user interfaces more easily. It provides pre-built components and libraries that simplify application design and development.
UI frameworks allow developers to focus on user experience, rather than dealing with the complexity of creating interface elements from scratch. Dart is the programming language that powers Flutter. Now that we know how Flutter and Dart are related, let's start by looking at Dart from a practical point of view, to help you see how to write and read Dart code.
Every Dart app starts with the top level `main` function. In this example, `main` is the entry point of the Dart application, including a Flutter application. The `print` function displays text on the console, which typically where is you are writing your application logic in Dart.
A variable is like a container that holds data. For example, if you want to store your age, you can create a variable called `age` and set it to your age number. Variables can hold different types of data data types and specify the kind of data a variable can hold.
So let's take a look at some type examples. Integer: the whole number, like five, minus five. Double: decimal numbers like 5.
5 String: text, like "Flutter" in this case or boolean: true or false values. Now let's look at how this works in Dart. The programming language used in Flutter, Dart, is statically typed language, meaning you must specify the variable type when you declare it.
Let's take a look at some examples. Here is an integer, a double, string and a boolean. You will define the type before the variable name.
Dart comes with built in types such as int, double, string, boolean, lists sets, maps and records. Then you will have the variable name and assign the value to the variable. And as you can see, having a semicolon is necessary when expression is complete.
Dart is a null safe language, which means variables must have a value and cannot be null, unless you specifically define that they can be. In programming, null means the absence of a value. Allowing variables to be null can cause issues at runtime if your code tries to use a variable that does not have a value.
To allow a variable to be null in dart, you can use the question mark in front of the type. Here are some examples. In this case, the variable can be null because of the question mark symbol.
Without a question mark, you will get an error if you try to assign null to a variable. Here is an example. You can declare variables in Dart without explicitly specifying their type using `var` keyword.
Dart uses type inference to determine the variables type based on its initial value. So here are some examples. As you can see, the Dart is going to infer the type based on the value that you are assigning to the variable.
You can also use `final` and `const` to define variables that cannot be reassigned. `final` is used for variables set once and then cannot be changed. While `const` is used for compile time constant, it's best practice to use "final const" where possible.
Dart supports the usual control flow of statements such as `if else` and `while`. These statements allow you to control the execution flow of your program based on conditions and loops. Dart is an object oriented programming language, which means it follows four principles: Encapsulation, inheritance, polymorphism, and abstractions.
Let's take a look at classes. Classes are the blueprint for creating objects. They encapsulate data for the object and method to manipulate that data.
The constructor for a class in Dart is named the same as the class name, and that's where you can use it for assignments to members. The class may have several members, including properties, name constructors, and methods. You can use the class by instantiating the constructor or named constructor and using them in your application.
In this case, you will get an instance of that class. Here are two examples of the instance of Flutter Flutter class Test1 and Test2. Functions are reusable blocks of code that perform a specific task in 'dart.
Functions can take parameters and return values. Here is an example. The add function.
where you can see the return type integer and it gets two parameters. In this case positional arguments. The first one is an integer and the second argument is going to be an integer two.
Note that even functions are objects in Dart with a type function. You have seen that we use positional arguments in all examples so far. Let's take a look at another concept in Dart: named argument, which you will see a lot in Flutter code.
In this example, the `greet` function has two named parameters: name and age. The named parameters are required, which means "must be provided" and cannot be null, while `age` has a default value of zero. Name arguments are specific using {curly braces} in the function definitions, and must be provided by name when the function is called.
You can also do the same with the class constructor arguments. One of the Dart stand out features is its support for asynchronous programming, which is crucial for developing responsive apps. Let's take a look at the difference between synchronous and asynchronous programming.
Asynchronous programming allows operations to happen in the background while your code continues to execute. The result of these operations will be resolved or rejected later, so your app does not need to wait for the operation to complete before moving on. Dart handles asynchronous operations using Future and Stream.
A Future represents a potential value or error that will be available at some point in the future. In this example, `fetchData` is an asynchronous function that simulate a network delay and returns a string. The `asynchronous` keyword indicates that this function is asynchronous, and `await` is used to wait for the future to complete.
The async and await keyword helps write more synchronous-like code while maintaining the asynchronous nature, making it easier to read and understand. A Stream is used to handle a sequence of asynchronous events. In this example, `countStream` generates a sequence of integers from one to max, with a one second delay between each number.
The `await for` loop processes events each time as it arrives. An asynchronous star keyword or `async*` keyword indicates that this function is the Stream. Notice that this function does not have a return and instead, it yields a value.
One more thing before we finish this video. The `import` and library directives can help you create a modular and shareable code base. Libraries not only provide APIs, but are a unit of privacy.
Identifiers that start with underscore are visible only inside a library. Every Dart file plus its parts is a library, even if it doesn't use a library directive. And here are some examples of using `import`.
So now that you define your libraries, you can go ahead and import a core one. Or you can even use the external packages. Or you can even import your local files that you are defining by using the `import` keyword.
Then everything that is public and doesn't use that underscore it will be available to be used in another file that you are importing those libraries to. This video only touches on the basics and core concepts of Dart. If you want to learn more and become an expert in the language, please check out the dart.
dev website for more information and learning. At its core, Flutter is a framework for building multiple platform applications. You can write your code once and run it on multiple platforms like Android, iOS, windows, Mac OS, Linux, and the web.
This multi-platform approach saves time and resources, allowing it to reach a broader audience with minimal effort. Flutter apps are compiled directly to native ARM code using Dart ahead of time compilation. This ensures high performance as your application runs like a native app on the target platform.
One of the Flutter's most celebrated features is Hot Reload. This allows you to see the result of your code change almost instantly without restarting your app. Flutter offers an expressive and flexible UI, which means the Widget based architecture allows you to build complex UIs quickly.
Everything in Flutter is a Widget, from simple buttons to complex layouts. This modular approach makes it easy to customize and extend your app's UI. If you want to learn more about Flutter, head over to flutter.
dev and learn more. Understanding the architecture is important as it helps you know how Flutter works under the hood and efficiently supports multiple platforms. Flutter is designed as an extendable, layered system and consists of three main layers: framework, engine, and embedder.
Let us start with the framework layer. The framework layer is the top most layer in Flutter. It provides a rich set of pre-designed widgets that you can use to build your user interface.
These widgets are organized in a hierarchical manner, forming a widget tree. The framework includes Material Design widgets for Android, and Cupertino widgets for iOS, allowing you to create visually appealing and platform-specific UIs. In addition to these widgets, the framework layer also provides various tools and APIs for handling animations, gestures, and rendering.
This layer is written in Dart, making it highly customizable and extendable. Next, let's talk about the engine layer. The engine layer is the middle layer in Flutter's architecture.
It renders the graphics and handles the lower level tasks. This layer is written in C++ and provides low level rendering support. The engine also includes a Dart runtime and a set of libraries that provides core services such as graphics, text layout and plugin architecture.
The engine plays an important role in translating the widgets into actual pixels on the screen. It also draws the UI, manages animations, and handles input events. The engine ensures that your app performs smoothly and efficiently, regardless of the platform it runs on.
Finally, let's discuss the embedding layer. The embedding layer is the bottom layer in Flutter's architecture. The layer provides platform-specific integration, ensuring that Flutter apps can run on different platforms.
The embedding embeds the engine in the target platform's native code, allowing the app to interact with platform-specific APIs and services. Each platform, such as Android, iOS, windows, macOS, Linux, and the web has its embedder. The embedder initializes the flutter engine, sets up the rendering surface, and handles platform-specific events.
This layer allows Flutter to maintain consistent behavior across different platforms, while leveraging each platform's unique capabilities. Understanding Flutter's architecture helps you appreciate the design choices behind Flutter and how it achieves high performance and cross-platform compatibility. In the next video, we will explore Flutter's widget-centric architecture and how widgets are central to building Flutter applications.
Widgets are the building blocks of a Flutter application, and understanding them is crucial for creating beautiful and functional user interfaces. In Flutter, everything is a Widget. Widgets describe what their view should look like given their current configuration and state.
They are immutable, meaning once a Widget is created, it cannot change. Instead, when something changes in the UI. A new Widget is created to reflect the change.
There are two primary types of Widgets in Flutter. Stateless Widgets and Stateful Widgets. Stateless Widgets are immutable and do not maintain any state.
They are useful for static content and doesn't change over time. In this example, my Stateless Widget extends Stateless Widget and overrides the `build()` method to describe the part of the user interface this Widget represents. Stateful Widgets are dynamic, and can change their state over time.
They are helpful for content that can change, such as user input or animations. In this example, the yellow bird extends `Stateful Widget` where it needs to create state, which as you can see, it's a `YellowBirdState`. The YellowBirdState's class then extend their State class where you can define the state for this Widget.
This `setState()` method is called to update the state and rebuild the UI. Let's take a closer look at another Stateful Widget. Stateful Widgets have a lifecycle that includes several methods.
So we're going to have `initialState()` that will be called when this Stateful Widget is created. You can initialize your state here. And in this case the state is going to be a variable counter.
A `build()` method is called whenever the Widget needs to be rendered. You describe the UI in this method, and a `dispose()` method is when the Widget is removed from the Widget tree. You can clean up resources in this case.
Understanding these lifecycle methods helps you manage your Widget's state efficiently. Flutter uses a declarative approach to build its UI. This means you describe what the UI should look like in their current state, and Flutter updates the UI when the state changes.
This approach contrasts with imperative UI frameworks, where you manually update the UI in response to state changes. Flutter's compositional model allows you to build complex UI by combining simpler Widgets. The result: a Widget tree.
As a UI becomes more complex, the Widget tree becomes longer and deeper, making it challenging to locate the specific Widgets. Luckily, you will have tools in FlutterFlow that can help you to locate your Widget in the Widget tree as easily as possible. The composability allows you to create many reusable Widgets that consist of other Widgets.
Flutter provides a rich set of built in Widgets for common tasks. Some examples include Containers like a Widget for layout, styling and positioning. Row and Column for arranging Widgets horizontally and vertically.
Stack for overlapping Widgets. ListView, and so on. You can explore this full range of built in Widgets in flutter.
dev, or stay tuned. We're going to go through many of them in the upcoming modules in this course. The Flutter toolchain consists of several stages that convert your Dart code into a natively compiled application.
These stages include Just in Time or JIT compilation and Ahead of Time AOT compilation. Let's break them down. During development, Flutter uses Just in Time compilation.
JIT allows for quick compilation of your code and enables one of Flutter's most powerful features: Hot reload. For production builds, for other uses ahead of time compilation. AOT compiles your Dart go directly to native machine code, significantly improving your application's performance.
AOT compilation ensures that your app runs efficiently with high performance, eliminating the overhead of interpreting code at runtime. So in this video, we're going to explore the differences between apps, modules, packages and plugins in Flutter. You may hear from them from time to time.
An app is a complete Flutter application that you can run on your various platforms like Android, iOS, web, and desktop. It contains everything needed to execute and present the application to the end user. Modules in Flutter are reusable pieces of code that you can integrate into existing applications.
This is especially useful for integrating Flutter into native Android and iOS apps. Flutter modules allow you to add Flutter views to your existing app without rewriting the entire application in Flutter. Packages are reusable libraries or components that add functionality to your Flutter apps.
They are designed to be shared and reused across multiple projects, and contain Dart code, assets and dependencies that provide a specific feature or functionalities. Plugins in Flutter are packages that provides an interface to platform specific APIs. They enable Flutter apps to access native functionalities like camera, Bluetooth and sensors which are unavailable in pure Dart packages.
Luckily, the Flutter CLI can help you create each of these and prepare for development. This is, of course beyond the scope of this course, but I put the resources in this slide so that you can go ahead and learn more if you want. pub.
dev is a package manager and repository for Dart and Flutter packages. It hosts thousands of packages created by the Flutter and Dart community, providing a wide range of functionalities you can integrate into your application. Simply, you can go to pub.
dev and search for any package that you are looking for or functionality. And once you find it, go ahead and in the next step you can install it. Adding a package to your Flutter project is straightforward.
Once you find the package that you want, you need to go ahead and use Flutter command line. That's one way of doing that. Or directly add it to the pubspec.
yaml file. In this case you need to run the command `dart pub get` in your terminal, which is going to fetch the package and make it available into your project. Once you install the package, then you need to import that into your application.
This is especially helpful when you work with generated code in FlutterFlow. Don't worry about it. We're going to get to this in the generated code module.
Stay tuned! If you are a web developer looking to dive into Flutter, this overview will help you transition smoothly. First, let's talk about the similarities between web development and Flutter development.
Declarative UI: Flutter and modern web frameworks like React use a declarative approach to building a user interface. In Flutter, you describe the UI using widgets, similar to how you can use components in frameworks like React. A single code base: Like in web development, where you often write code across different browsers, Flutter allows you to write a single code base that runs in multiple platforms, including web, mobile, and desktop.
Hot reload: Flutter's Hot Reload feature is similar to live reloading in web development. It lets you see the changes you make in your code almost instantly without restarting the app, speeding up the development process. Now let's take a look at some key differences in web development.
The browser's rendering engine displays content in flutter. The engine layer is responsible for rendering everything. This gives you more control over the UI, but also means you must manage more aspects of the rendering process.
Web developers use HTML and CSS for layout and styling, whereas Flutter builds the UI using the Widget Tree. Widgets in Flutter can be considered a combination of HTML elements and CSS style encapsulated into a single object. While state management in web development can be handled with libraries like Redux and Context API in React, and many more, Flutter has its state management solution such as provider, RiverPod and BloC.
There's also a built in state management in Flutter. Web developers typically use browser based developer tools for debugging. Like all of you probably know, the DevTools.
In Flutter, you use tools like the Flutter DevTools, which provides performance and debugging tools designed explicitly for Flutter application. So if you want to debug your Flutter application, you need to use Flutter DevTools. The 1 to 1 comparison between Flutter and Web is beyond the scope of this course.
However, Flutter docs have provided an in-depth comparison for web developers to learn Flutter and Dart by comparison. Head over to the link that you are seeing on the screen and learn more about web and Flutter comparisons If you have experience in native Android or iOS development, this overview will help you understand how to leverage your skills in Flutter. Let's talk about similarities.
Flutter performs well by compiling Dart code to native code. This ensures your app runs smoothly, just like a native app. Flutter and Native Development use a components- based approach to building UI in Flutter.
These components are called Widgets, similar to Views in Android or iOS. Managing this state is a similar concept in both native and Flutter development. While Flutter offers a state management solution, the underlying principles are similar to those native developments.
But now let's take a look at some of the key differences. Unlike native development, which requires writing separate code bases for Android and iOS, Flutter allows you to write a single code base that runs on both platforms, which significantly reduces development time and maintenance effort. Flutter Hot Reload feature lets you see the result of your code changes almost instantly without restarting your app.
This is a significant improvement over the typical compile/deploy cycle in native development. In native Android, you use XML for layouts, and in iOS you use storyboards or Swift UI. In Flutter, you build UIs using a widget tree directly in code, which can be more flexible and expressive.
Native development uses platform specific tools like Android Studio and Xcode, while you can still use these IDEs for Flutter development. Flutter also provides tools like Flutter DevTools for performing profiling and debugging. You can also use any IDE for building your Flutter applications.
The 1 to 1 comparison between Flutter and each native platform or cross-platform framework is beyond the scope of this course. However, you can check out the Flutter docs for an in-depth comparison. As a backend developer, you're familiar with building and managing server side logic, databases and APIs.
Flutter can interface with backend systems, making it a powerful tool for full stack development. Let's see how you can leverage your expertise in backend development and complement it with Flutter capabilities, enabling you to create end-to-end solutions. One of the primary tasks when developing a Flutter app is connecting it to a backend service.
This could be a REST API, a WebSocket server, or any other backend systems. Managing state is critical to connecting the front end and backend services. Flutter provides various state management solutions which you can leverage to manage this state effectively.
Implementing authentication and authorization is a common task for backend developers. Flutter can integrate with various authentication providers and backend services to handle user authentication, so they can interact with various databases, both local and remote. For local storage, you can use the SQLite package or other services for packages and for remote databases, you typically interact through APIs.
You can leverage your backend development skills to build full stack applications with Flutter.
Related Videos
Copyright © 2025. Made with ♥ in London by YTScribe.com