Cross-Platform Mobile Apps with Flutter
Table of Contents
IntroductionMaximiliano Firtman begins the course by explaining the system requirements and development tooling required to make applications with Flutter. Developers can use Windows, Mac, Linux or ChromeOS to create applications. In order to compile an iOS application, a Mac computer is required.
Mobile Dev & Flutter OverviewMaximiliano describes the general process of building native application and the tooling options available. Flutter utilizes a cross platform SDK which allows developers to target many operating systems including Apple platforms, Android, Windows and Linux. Applications built with flutter can also create progressive web applications (PWAs).
Dart OverviewMaximiliano introduces Dart, a programming language created by Google. It is a versatile language because the same codebase can be compiled into source code, bytecode, or machine code depending on the targeted platform. A question about Dart's optional null-safety feature is also covered in this segment.
Variables & TypesMaximiliano explains variable types can be explicitly declare or inferred. When the var keyword is used to declare a variable, Dart will infer the type and throw an error if a different type is assigned to the variable later in the application. All types in Dart are class-based objects.
Functions & LambdasMaximiliano walks through function syntax. Arguments can be either positional or named. If a function uses named arguments, they can be passed in any order. Lambda functions use a fat arrow and can only return a single expression.
Functions Q&AMaximiliano answer questions about function parameter syntax, optional parameters and if void has a type.
ClassesMaximiliano explains how classes are created in Dart. Classes can have a traditional primary constructor or utilize any number of named constructors which are typically prefixed with "from". There are no interfaces in Dart but developers can create abstract classes.
Flutter OverviewMaximiliano explains that Flutter is Google's UI toolkit for building natively compiled applications for mobile, web and desktop platforms from a single codebase. Developers have the option to create their own UI components, use Material UI, or Apple's Cupertino. It's recommended to use Material UI since it's saves development time and will be more consistent across platforms.
Flutter Project Setup: Android StudioMaximiliano creates a new Flutter project using Android Studio. In the project settings, reverse domain notation is used to create a unique package name for the project. The targeted platforms can also be selected. Once the project is created, developers can select a default device for previewing the project.
Flutter Project Setup: VS CodeMaximiliano creates a new Flutter project in Visual Studio Code. After the Flutter extension is installed, the project can be created from the command palette. VS Code will generate a default project and show the available testing platforms in the taskbar at the bottom. The Run/Debug button can be used to build and preview the project.
Flutter Code TourMaximiliano walks through the project structure and explains how the generated files are used. There are individual folders for each application platform container. The lib directory will contain all the Dart files for the project. If there are issues running the project, the command "flutter doctor" can be run to analyze SDK installation and report any issues.
Text & Layout WidgetsMaximiliano explains how every Flutter application extends from a subclass of Widget. Any Widget must receive a key in its constructor and implement a build method. A basic example class containing a Text widget is used to demonstrate layout and container classes.
StatelessWidgetMaximiliano demonstrates the functionality of a class that extends StatelessWidget. A text input field is added to update the name variable. However a StatelessWidget will never rerender itself so the new value is never updated on screen.
StatefulWidgetMaximiliano refactors the widget to extend from the StatefulWidget class. Now when the name property is updated, the new value is rendered on screen. Reactive properties cannot be declared in the build method. They should be declared a class property. The setState method is used to change the value of the property.
Widget StylesMaximiliano demonstrates how to style Flutter widgets. Some styling can be applied by wrapping a widget in a styling widget like the Padding widget. Other styles can be applied with the styles property.
Adding AssetsMaximiliano creates an images directory and adds images from the course assets. The location of the assets folder is added to the pubspec.yaml configuration file. Higher resolution versions of each image can be placed in, 2.0x, 3.0x, and 4.0x folders. Flutter will automatically use the appropriate resolution. Material Design swatches are also discussed in this segment.
Creating the Offers PageMaximiliano create the OffersPage component in a new Dart file. The Material UI package is imported and Text widgets are added for the title and description of each offer. The main application is updated to display the OffersPage as the home page.
Styling the Offers PageMaximiliano uses the Center widget to wrap each Text widget to keep them centered on screen. Padding widgets are also applied to add some spacing. Utilizing the built-in theme API for setting text size is also demonstrated in this segment.
Creating the Card LayoutMaximiliano uses the Card component to create an elevated look to the offer. The BoxDecoration widget is introduced to add a background image to the card. Additional strategies for using background images are also discussed in this segment.
Handling OverflowMaximiliano continues to style the Card widget by applying a background color to the text fields and some additional padding to the container. Overflow within a container is addressed by using a ListView widget as the container. Scrollbars will automatically appear as needed.
Bottom NavigationMaximiliano uses the BottomNavigationBar widget to add navigation to the bottom of the application. The Material UI library includes a number of icons that can be used in the navigation. The BottomNavigationBar widget has an onTap event that can be used to update the selected index of the navigation and rerender the correct widget in body.
Rendering PagesMaximiliano creates Dart files for the MenuPage and the OrdersPage widgets. These widgets can now be rendered as the navigation changes. A question about managing the index of the navigation is also answered in this segment.
Pages Data ModelMaximiliano creates Product, Category, and ItemInCart classes for the application's data model. The product class uses a computed property to construct the imageURL for a product instance. Since the computed property only has a getter, it is read-only.
ProductItem Widget LayoutMaximiliano creates a ProductItem widget to display the image, title, and price of a product. Many layout widgets have a padding property which can be used to apply padding instead of wrapping the widget in a Padding widget.
Adding ButtonMaximiliano creates a button to add an item to the order. Buttons have an onPress property for handling the event and a child property for the content within the button. An onAdd function is declared at a property of the ProductItem class and behaves like a callback for the button's onPress event.
Creating a Data ManagerMaximiliano creates a DataManager class to manage the items in the cart. The class contains methods for adding, removing, and clearing items. Since the data manager needs to be accessed by both the menu page and the orders page, it is declared in the parent class and passed to each page.
Rendering Data with FutureBuilderMaximiliano uses a FutureBuilder to display the categories returned by the API call. FutureBuilders are able to determine the status of the API request and render different widgets on the based on if the data is loaded, is completed, or had an error.
Nesting ListView WidgetsMaximiliano displays the products under each category by nesting a ListView widget inside the category ListView. When ListView widgets are nested, they will have conflicting scroll behavior. This can be eliminated by using the ClampingScrollPhysics method to instruct the inner ListView to ignore the scroll events.
Laying Out the Order PageMaximiliano adds layout logic to the order page do display the products in the cart. The Expanded widget is introduced and behaves similarly to a CSS flexbox layout. Percentages are provided to size items across a row or column.
Adding and Removing ProductsMaximiliano completes the order page by adding the ability to add and remove items. Since removing the items requires the user interface to be updated, the OrderPage widget must be a Stateful widget and the cartRemove method should be called in a setState method.
Responsive DesignMaximiliano demonstrates how Flutter handles responsive design. Media queries can be used to return different layout widgets depending on the size of the screen. Other containers, like the Wrap widget, can tile widgets to fit the screen.
Building for Android & iOSMaximiliano demonstrates how to build the project for both Android and iOS. Both Android Studio and XCODE provide a helpful interface for creating icons and configuring metadata. iOS apps can only be built from a Mac computer.
Building a PWAMaximiliano demonstrates how to build a Progressive Web Application (PWA). The PWA version will run as a website in any browser. However for browsers that support PWAs, the application can be installed and run as a standalone application on the operating system.