Cross-Platform UIs with Flutter - Ryan Edge - E-Book

Cross-Platform UIs with Flutter E-Book

Ryan Edge

0,0
26,99 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.
Mehr erfahren.
Beschreibung

Build a variety of dynamic projects and beautiful UIs as you explore the power of Flutter for the web, desktop, and mobile


Key Features


Discover state management solutions with InheritedWidget and the Provider package


Create responsive and beautiful UIs with the Material and Cupertino libraries


Explore animations, forms, gestures, and backend integration with Supabase


Book Description


Flutter is a UI toolkit for building beautiful, natively compiled applications for mobile, web, desktop, and embedded devices from a single code base. With Flutter, you can write your code once and run it anywhere using a single code base to target multiple platforms. This book is a comprehensive, project-based guide for new and emerging Flutter developers that will help empower you to build bulletproof applications.


Once you start reading book, you’ll quickly realize what sets Flutter apart from its competition and establish some of the fundamentals of the toolkit. As you work on various project applications, you’ll understand just how easy Flutter is to use for building stunning UIs. This book covers navigation strategies, state management, advanced animation handling, and the two main UI design styles: Material and Cupertino. It’ll help you extend your knowledge with good code practices, UI testing strategies, and CI setup to constantly keep your repository’s quality at the highest level possible.


By the end of this book, you'll feel confident in your ability to transfer the lessons from the example projects and build your own Flutter applications for any platform you wish.


What you will learn


Create responsive and attractive UIs for any device


Get to grips with caching and widget trees and learn some framework performance tips


Manage state using Flutter’s InheritedWidget system


Orchestrate the app flow with Navigator 1.0 and 2.0


Explore the Material and Cupertino built-in themes


Breathe life into your apps with animations


Improve code quality with golden tests, CI setup, and linter rules


Who this book is for


This book is for software developers with a good grasp of Flutter, who want to learn best practices and techniques for building clean, intuitive UIs using a single codebase for mobile and the web. Prior experience with Flutter, Dart, and object-oriented programming (OOP) will help you understand the concepts covered in the book.


 

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB

Seitenzahl: 201

Veröffentlichungsjahr: 2022

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Cross-Platform UIs with Flutter

Unlock the ability to create native multiplatform UIs using a single code base with Flutter 3

Ryan Edge

Alberto Miola

BIRMINGHAM—MUMBAI

Cross-Platform UIs with Flutter

Copyright © 2022 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

Group Product Manager: Rohit Rajkumar

Publishing Product Manager: Ashitosh Gupta

Senior Editor: Hayden Edwards

Content Development Editor: Abhishek Jadhav

Technical Editor: Saurabh Kadave

Copy Editor: Safis Editing

Project Coordinator: Rashika Ba

Proofreader: Safis Editing

Indexer: Hemangini Bari

Production Designer: Joshua Misquitta

Marketing Coordinator: Elizabeth Varghese and Teny Thomas

First published: August 2022

Production reference: 1240822

Published by Packt Publishing Ltd.

Livery Place

35 Livery Street

Birmingham

B3 2PB, UK.

ISBN 978-1-80181-049-4

www.packt.com

To my parents, Judy and Stephen Edge, for their constant support and for

exemplifying love, faith, and determination. To my wife Erica, and children,

Amaya, Tristan, and Bryce, for putting up with all of my shenanigans.

– Ryan Edge

To my beloved Giorgia, my family, and all my friends.

– Alberto Miola

Contributors

About the authors

Ryan Edge is an experienced software engineer, with over 10 years of experience as a web and mobile developer. He graduated in computer science from Southern Polytechnic State University. He is currently working for a stealth start-up and part-time as a freelancer, with over 3 years of professional experience in Flutter. He is a Google Developer Expert in Flutter, an active member of the open source community, and a co-organizer of his local Flutter meetup group.

Alberto Miola is an Italian software engineer who graduated in computer science from the University of Padua. He’s currently working with Dart and Flutter, with which he has more than 3 years of professional experience, and also is a Dart and Flutter GDE. He attends online conferences, writes technical articles about Flutter, and is also the author of the Flutter Complete Reference book series.

About the reviewers

Amit Bhave is an experienced full stack developer, having worked on various languages and frameworks such as Flutter, Java, Kotlin, Spring Boot, Micronaut, and so on. He currently works as a senior engineer at Getir, a Turkish delivery services company. Previously, he has also worked at ThoughtWorks.

Ivan Rendulić is an experienced software developer and architect with more than 20 years in the software industry. He started programming in the fifth grade and is still enjoying working with and exploring new and progressive technology. He is currently working for his own consulting and development company, Butterfly Design (Croatia).

He fell in love with Flutter at first sight. He considers himself a passionate Flutter enthusiast. He has led and developed greenfield Flutter projects for clients in Croatia. Here are a couple that he is most proud of:

Mobility One, Mobility One project, CroatiaDream Agency, Kali Sara App project, Croatia

He wants to pass on his full regards to his colleagues and associates:

Alperen Yalcin (Turkey, alper50)Carlos Eduardo De Oliveira (Brazil, github-carlos)David Machara (Botswana, SidneyMachara)

Also, he wants to pass on his regards to the Flutter Croatia Community:

Marko Filipović (Croatia, markfili)Sandro Lovnički (Croatia, slovnicki)

Table of Contents

Preface

1

Building a Counter App with History Tracking to Establish Fundamentals

Technical requirements

Understanding the foundations – widgets, elements, and render objects

Setting up the project

Creating an enhanced counter app

The title widget

The counter widget

The history widget

Manually caching a widget

Making everything constant

Summary

Further reading

2

Building a Race Standings App

Technical requirements

Setting up the project

Localization and internationalization

Routes management

Adding a custom font

Creating the race standings app

The HomePage widget

The NextRaces widget

Summary

Further reading

3

Building a Todo Application Using Inherited Widgets and Provider

Technical requirements

Sharing dependencies in a Flutter application

Setting up the project

Creating the Todo application

Using InheritedWidget for state management

Refactoring with Provider

Summary

Further reading

4

Building a Native Settings Application Using Material and Cupertino Widgets

Technical requirements

Understanding that everything is a widget

Setting up the project

Building a platform-specific UI

Building an iOS-specific UI with CupertinoApp

Building an Android-specific UI with MaterialApp

Summary

Further reading

5

Exploring Navigation and Routing with a Hacker News Clone

Technical requirements

Setting up the project

Understanding navigation

Imperative routing with Navigator 1.0

Declarative routing with Navigator 2.0

Simplifying Navigator 2.0 with GoRouter

Summary

Further reading

6

Building a Simple Contact Application with Forms and Gesturess

Technical requirements

Setting up the project

Building forms the manual way

Building complex forms with the Form/FormField widgets

Custom form validation

Summary

Further reading

7

Building an Animated Excuses Application

Technical Requirements

Setting up the project

Working with animations in Flutter

Building implicit animations in Flutter

Building implicit animations using Flutter’s animations package

Summary

Further reading

8

Build an Adaptive, Responsive Note-Taking Application with Flutter and Dart Frog

Technical requirements

Setting up the project

Introduction to responsiveness and adaptiveness

Making an app responsive

Making an app adaptive

Creating REST endpoints for the Notes application

Summary

Further reading

9

Writing Tests and Setting Up GitHub Actions

Technical requirements

Setting up the project

Writing tests for the Flutter app

Writing unit tests

Writing widget and golden tests

Exploring GitHub actions and repository quality

Creating the GitHub workflow file

Code coverage

Summary

Further reading

Index

Other Books You May Enjoy

Preface

Flutter is a UI toolkit for building beautiful, natively compiled applications for mobile, web, desktop, and embedded devices from a single code base. With Flutter, you can write your code once and run it anywhere using a single code base to target multiple platforms. This book is a comprehensive, project-based guide for new and emerging Flutter developers that will help empower you to build bulletproof applications.

Once you’ve picked up the book, you’ll quickly realize what sets Flutter apart from its competition and establish some of the fundamentals of the toolkit. As you work on various project applications, you’ll understand just how easy Flutter is to use for building stunning user interfaces. The book covers navigation strategies, state management, advanced animation handling, and the two main UI design styles: Material and Cupertino. It’ll help you extend your knowledge with good code practices, UI testing strategies, and CI setup to constantly keep your repository’s quality at the highest level possible.

By the end of this book, you’ll feel confident in your ability to transfer the lessons from the example projects and build your own Flutter applications for any platform you wish.

Who this book is for

This book is for software developers with a good grasp of Flutter who want to learn best practices and techniques for building clean, intuitive UIs, using a single code base, for mobile and the web. Prior experience with Flutter, Dart, and object-oriented programming (OOP) will help you understand the concepts covered in the book.

What this book covers

Chapter 1, Building a Counter App with History Tracking to Establish Fundamentals, is about Flutter’s core concepts. This chapter explores widgets, elements, render objects, and the rebuild system.

Chapter 2, Building a Race Standings App, is about layout and responsiveness. The project in this chapter covers internationalization, responsiveness, and layout strategies for high-quality applications.

Chapter 3, Building a Todo Application Using Inherited Widgets and Provider, is about sharing data in an application. You will learn about property forwarding and how to create inherited widgets.

Chapter 4, Building a Native Settings Application Using Material and Cupertino Widgets, is about building an application that looks native to iOS or Android. You will learn how to use Flutter’s Material and Cupertino widgets.

Chapter 5, Exploring Navigation and Routing with a Hacker News Clone, is about handling transitions between a multi-screen application. You will learn how to use Navigator, an imperative routing mechanism, and GoRouter, a declarative routing mechanism.

Chapter 6, Building a Simple Contact Application with Forms and Gestures, is about capturing user input and turning that input into application data. You will learn how to use Flutter’s Form and Gesture components.

Chapter 7, Building an Animated Excuses Application, teaches you how to build smooth animations in an application designed to give us random excuses to miss work.

Chapter 8, Build an Adaptive, Responsive Note-Taking Application with Flutter and Dart Frog, is about adapting an application to behave differently on different platforms and display information differently in different screen sizes. You will learn how to use Flutter’s adaptive and responsive APIs.

Chapter 9, Writing Tests and Setting up GitHub Actions, is about testing Flutter apps and creating a CI pipeline to run tests. You will learn how to use GitHub actions along with our Flutter project.

To get the most out of this book

You will need to install Flutter on your machine, which already includes the Dart SDK, so you will get both with a single installation. We created and tested our project with Flutter 3, so make sure to use any version greater than this.

If you are using the digital version of this book, we advise you to type the code yourself or access the code from the book’s GitHub repository (a link is available in the next section). Doing so will help you avoid any potential errors related to the copying and pasting of code.

Download the example code files

You can download the example code files for this book from GitHub at https://github.com/PacktPublishing/Cross-Platform-UIs-with-Flutter. If there’s an update to the code, it will be updated in the GitHub repository.

We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Download the color images

We also provide a PDF file that has color images of the screenshots and diagrams used in this book. You can download it here: https://packt.link/e2h8M.

Conventions used

There are a number of text conventions used throughout this book.

Code in text: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: “Next, open the pubspec.yaml file and make sure to have these two dev dependencies installed:”

A block of code is set as follows:

dev_dependencies:   # https://pub.dev/packages/dart_code_metrics   dart_code_metrics: ^4.9.1   # https://pub.dev/packages/flutter_lints   flutter_lints: ^1.0.4

When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:

class TodosApp extends StatelessWidget {   const TodosApp({     Key? key,     required this.todoController,   }) : super(key: key);   final TodosController todoController;

Bold: Indicates a new term, an important word, or words that you see onscreen. For instance, words in menus or dialog boxes appear in bold. Here is an example: “Create a new Flutter project in your favorite IDE and make sure to enable web support by clicking on the Add Flutter web support checkbox.”

Tips or Important Notes

Appear like this.

Get in touch

Feedback from our readers is always welcome.

General feedback: If you have questions about any aspect o-f this book, email us at [email protected] and mention the book title in the subject of your message.

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/support/errata and fill in the form.

Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.

Share your thoughts

Once you’ve read Cross Platform UIs with Flutter, we’d love to hear your thoughts! Please select https://www.amazon.in/review/create-review/?asin=1801810494& for this book and share your feedback.

Your review is important to us and the tech community and will help us make sure we’re delivering excellent quality content.

1

Building a Counter App with History Tracking to Establish Fundamentals

When you decided to buy this book, you had probably already played with Flutter a bit or even already worked with it. We have organized this book in a way that chapters gradually increase in difficulty, and they can be read in any order. Even if you aren’t a Flutter master, you will still be able to get through all the chapters, thanks to in-depth analysis, images, and code snippets. When you arrive at the end of the book, you’ll be able to build Flutter apps up to version 2.5 in a professional and performant way.

When you create a new Flutter project, regardless of whether you’re using Android Studio or Visual Studio Code (VS Code), a new counter app is created for you. This is the default template used by the framework to set up a simple app you can run on mobile, desktop, and the web. In the first chapter, we’ll be building an enhanced version of the counter app that also keeps a history of the increased values. Even if it may seem a trivial app to build, you’ll see that there are many considerations to make.

In this chapter, we will mainly touch on three areas, as follows:

Understanding the foundations – widgets, elements, and RenderObjectsSetting up the projectCreating an enhanced counter app

You may be surprised to discover how a simple app actually requires various bits of knowledge to be efficiently created. Mastering constant widgets, elements, state, and much more is the key to success. We’re first reviewing some important theories about Flutter’s foundations, and then we will start coding. Without further ado, let’s dive in!

Technical requirements

Flutter runs on Windows, macOS, and Linux, so you don’t really need to worry about the operating system. Make sure to have your Flutter version updated to the latest version in the stable channel and create a new project using—preferably—Android Studio or VS Code. If you’re brave enough, there is also the possibility of coding on a simple text editor and then manually building and running projects, but this is quite inconvenient. To make sure that your Flutter environment is correctly set up, you can run the flutter doctor command in the console and check the output.

If you’re looking for a complete Flutter installation guide, make sure to check the official documentation at https://flutter.dev/docs/get-started/install.

For now, we will ignore the test folder, but I promise we will come back to it in Chapter 9, Writing Tests and Setting Up GitHub Actions, where we will test our app and publish it to GitHub.

To keep the code clear and concise, we have removed colors and styling portions from the various snippets across the chapter. The complete code can be found at https://github.com/PacktPublishing/Cross-Platform-UIs-with-Flutter/tree/main/chapter_1. You will find two folders because we’re first building a good but improvable version of our project, and then a better version later.

Understanding the foundations – widgets, elements, and render objects

Before moving to the project creation, we want to review some fundamental concepts of the Flutter framework: Widget, Element, and RenderObject types.

While a widget tree is created and managed by the developer, the Flutter framework builds and manages two other trees in parallel, called an element tree and a render object tree. At a very practical level, these three trees are used to build user interfaces (UIs) and decide when it’s time to refresh them. At the highest level, there are widgets, and they come in two flavors, as outlined here:

StatelessWidget: This kind of widget doesn’t require a mutable state and is best used to describe those parts of the UI that never change. Stateless widgets are immutable.StatefulWidget: This kind of widget has a mutable state and is generally used when the developer needs to control the widget’s life cycle or dynamic contents. Stateful widgets are immutable too.

Note that both kinds of widgets in Flutter are immutable because all of their parameters—if any—are final. A StatefulWidget itself is immutable but its state is mutable, and it’s represented by a separated State<T> object. Whenever the UI needs to be updated, Flutter follows this logic:

If a widget is initialized with a const constructor, then nothing special happens and the framework just skips to the next child. This is one of the main reasons why you should try to use constant constructors as much as possible.If a widget isn’t initialized with a const constructor, then it’s removed and regenerated with a new one. This is totally fine; Flutter has been built for this exact purpose and is really fast at replacing widgets.

When Flutter rebuilds a widget, it uses the Element object associated with that widget to compare the old and new instances. In case of changes, the UI is updated; otherwise, nothing happens and the framework proceeds to visit the next child.

Note

Don’t think that StatelessWidget is less efficient than StatefulWidget. They are both subclasses of Widget and they’re treated in the same way! The only difference is that a stateful widget has a State class too, which survives to rebuilds because it’s stored in the Element object behind that widget.

In general, StatefulWidget is used when the widget needs a one-time initialization or it has to change whenever the configuration updates. The State class has a few useful methods for this purpose, as outlined here:

void initState(): This method is called only once when the widget is created—it’s like the constructor of a widget.void didChangeDependencies(): This is called right after initState() and it’s used to perform initialization based on an InheritedWidget above it.void didUpdateWidget(covariant T oldWidget): This is called whenever the widget configuration changes. For example, this method is invoked whenever a widget’s parameter value is changed.void dispose(): This is called when the widget is removed from the tree—it’s like the destructor of a widget.

If you don’t need to use any of the preceding widget life cycle methods and don’t use setState(), then StatelessWidget is the best choice.

Having three trees allows Flutter to only repaint the UI when it’s really needed. Element objects are the glue between the configuration we want to create (widgets) and the actual implementation in the UI (render objects). They detect widget changes and decide whether a render object has to simply be updated or removed and recreated. Let’s see a concrete example here:

Widget build(BuildContext context) {   return  Container(     width: 250,     height: 250,     color: Colors.white,     child: const Text('I love Flutter!'),   ); }

When it’s time to render the UI, Flutter traverses the widget tree and calls the build method of the various stateful or stateless widgets. At the same time, it builds the element and the render tree by calling createElement() and createRenderObject(), respectively, on the widget being built. The actual situation that the framework is dealing with in the end is shown in the following screenshot:

Figure 1.1 – The widget, element, and render trees

Here’s what’s actually happening under the hood:

Every widget has an associated Element object that holds the state (in the case of stateful widgets) and is used by the framework to detect changes on the widget that might require a repaint of the UI.Elements are backed by a RenderObject that contains all the logic to paint graphics on the screen and is relatively expensive to create. It takes care of hit testing, painting, layout constraints, and much more.When a widget changes (using setState(), for example), the underlying element is marked as dirty and the framework triggers the build method to be called. Elements compare the differences between the old and the newly modified widget to update or recreate the render box.Render boxes are modified and kept in the framework’s cache as much as possible. They are recreated only when the widget type is different. They’re generally recreated only when the widget type changes or there are too many variations to apply. Updating or modifying a render object also updates the UI.The RenderObject is the one that actually has instructions to paint the UI. The Flutter framework uses elements to decide which changes, if any, have to be applied to a render object.

When you use the const constructor on a widget, you can save Element comparisons, RenderObject modifications, or (even better) recreations, plus other compiler and framework optimizations. Flutter already knows about the widget’s location on the tree; the BuildContext variable is nothing more than the framework giving you access to the element behind your widget.

On the other hand, functions are always evaluated. When we put a function directly inside the build method, the returned widget (along with the Element and RenderObject types) will always be re-evaluated. Functions cannot be more efficient than an optimized, constant class hierarchy, however.

Here’s a small comparison of the two widget-creation approaches, with the advantages they bring.

The only advantage functions give you is that we have less code than if creating a new class extending StatelessWidget or StatefulWidget.

Widgets instead have a lot more advantages, such as the following:

They can have a constant constructor and allow for granular rebuilds.They can have keys.Flutter can skip the rebuild of a widget if it didn’t change by looking at its Element object.They’re well integrated into the Object Inspector, which may be essential in certain debugging scenarios.Hot reload always works as expected.There’s no risk of reusing some previous state because they correctly dispose of all the resources.Since they have an Element object behind them, you can use the BuildContext object and its application programming interface (API).They follow the single-responsibility principle (SRP) and lead to more maintainable, extensible, and testable code.

As you can see, preferring widgets over functions is a great idea because you can get so many advantages for free. The only optimization you need to do is using const in front of the constructor’s name, and Flutter will take care of the rest.

Let’s now jump into the practical side of things, where you see how this theory can be useful when building an efficient Flutter app!

Setting up the project

To really get started, create a new Flutter project with your favorite integrated development environment (IDE) to get the skeleton of a minimal, working Flutter app. Next, open the pubspec.yaml file and make sure to have these two dev dependencies installed:

dev_dependencies:   # https://pub.dev/packages/dart_code_metrics   dart_code_metrics: ^4.9.1   # https://pub.dev/packages/flutter_lints   flutter_lints: ^1.0.4

We’re now going to dedicate some time to work on the analysis_options.yaml file. Very simply, this file contains a series of static analysis rules to help you with writing readable, high-quality code. By default, a new Flutter project already creates this file for you with a minimal setup (we have removed comments for simplicity), as illustrated in the following code snippet:

include: package:flutter_lints/flutter.yaml linter:   rules:     avoid_print: false     prefer_single_quotes: true

The flutter_lints package included in the file adds a series of static analysis rules recommended by the Flutter team. While this setup is fine, we suggest you improve it with stricter rules and static analysis parameters in order to do the following:

Make sure to adhere to the Dart and Flutter standard coding practices.Improve your code quality even more.Increase the possibility of finding potential bugs even before compiling your code.

We get the first point for free because a new Flutter project already generates the minimal static analysis setup for us. For the other two points, we can use a well-known package called dart_code_metrics