When we are developing mobile Flutter applications, we know we can make use of flavors. Flavors allow us to handle different configurations for different environments — development, staging, production — adding custom assets and settings to each version of the app.
However, we don’t have the same in Flutter for Web. And sometimes it poses a problem — how can we create different versions of the same web application using a system like flavors? For example, how can we have different keys for JS libraries like Google Maps or have different Firebase configurations initialised in our Index.html file?
In this article we are going to explore how we can add these configurations dynamically and per environment. …
At 3Rein, our goal is to provide highly adaptable solutions that streamline operations in the equine industry. We aim to improve the welfare of horses and provide a competitive edge to athletes by using novel, scalable technologies to reduce administrative responsibilities through digitization and to improve services through automation.
As part of this process, our development team is creating multiple, reusable, interactive software applications, each requiring a set of software dependencies. Often, these dependencies are also used by other applications. Instead of creating a copy of the same dependencies for each application, we create individual packages of dependencies that can be shared by multiple projects (as discussed in the article, Modular Flutter Apps — Design and Considerations). …
Whether we are starting a new Flutter project for web, mobile or desktop, there are two thing that will be common in all projects: the pubspec.yaml
and pubspec.lock
files. In this article we will explore the pubspec.yaml
file - what it is and what we can do with it.
When we create a new Flutter Project, we usually have the following file tree:
But what is exactly inside the pubspec.yaml
file? Let's examine it:
As we can see, the pubspec.yaml
file is divided into different sections, let's dive deep into each one.
At the top of the file we see the name
. This field dictates the package name, and also how we will import files inside this project or from this project. For example, if in one file we want to import the main.dart
function, the import will be as…
When building cross-platform applications that can run on web, mobile and desktop, we often don’t need to access the underlying platform — we are either showing static data or we are communicating with a backend server to post and display newdata.
However, there are cases in which we need to retrieve some information about the platform — device’s specifications, location or hardware such as camera and sensors — or even access a specific native library or API, which requires us to communicate with the platform’s native code.
With Android and iOS we use Platform Channels to send and receive messages from the native platform, and we can use PlatformViews to display native UI views on Flutter. …
When starting up a Flutter application, be it in mobile or web, there is a blank screen displayed before the app shows its first screen. In reality, what happens is that the Flutter framework engine is “booting up” before being able to show the first screen, so by default it shows a white screen.
In both Android and iOS, we can change this by using a Native Splash Screen, since it’s something that native apps extensively use for branding and initialization.
In Material Design, when we want to give some subtle feedback to the user, we may be inclined to use a SnackBar:
Every time we start a new Flutter project, there’s a single line of code that most of the times we don’t need to change. This line ensures that our Flutter app is started and shown to the user.
We can read this line of code as a simple sentence: our main
function for this project will run an app called MyApp
. As with many other programming languages, the main
function is the entry point of our application, telling Dart where it should start running our code.
And though this works perfectly for some apps, we may encounter some issues as our projects grows in scale and complexity…
When working in a big project in native Android Development, we may suffer a lot from long build times and an incoherent code structure. That’s why many projects tend to divide their codebase into multiple modules. This ensures not only that the project is divided into smaller units that can be independently changed but it also reduces build time since each module can be built separately and, if a module has not been changed, when building the app it won’t be rebuilt. …
When doing any IT project, we sometimes don’t think on the weight of every decision we are making. Abstracting too much or too less, using X, Y or Z library, gluing up code that “will be fixed later”, and so many other countless examples. Each of these decisions has a cost. The peculiar thing is that that cost is going to bite us back not today, not tomorrow, but eventually, and when that “eventual” day comes, we may lose hours, days or weeks trying to retrace our steps or fixing our mess of a codebase.
This article is going to expose one of those stories. It’s not an article about how to create the “perfect architecture”, nor the best approaches for each problem, but it is an article about how I struggled with these issues and how I found a solution that, for the moment, works perfectly in my case. …
Sometimes we don’t need complex apps, sometimes we just need an app that displays a list of items from one endpoint, and we can manage to do it with a simple method:
And we don’t have any errors, there’s no need to log our responses. What about cache? Nobody cares about it!
But truth be told, almost no apps are as simple as this. Some do require more in order for us to get the response from the server or debug our application, such as:
About