Case Study: How I Created a Demo Mobile App in Flutter for Different Domains
I created a demo project for use by businesses that sell products and services of various types. This app has a catalog, product profiles and ratings. The content in the app can be changed easily, so clients are able to get a personalized demonstration product in a short amount of time.
I created a demo project for use by businesses that sell products and services of various types. This app has a catalog, product profiles, and ratings. The content in the app can be changed easily, so clients are able to get a personalized demonstration product in a short amount of time. Animation is this app’s main feature: I created beautiful transitions between screens, especially between the catalog and product pages. In this case study, I’ll tell you how I developed this small demo project, what challenges I encountered, and how this project will be used next.
Why I chose Flutter
I’m an iOS developer, and recently I began to learn Flutter. I see it as a great technology that’s now suitable for small projects and that will only become more powerful in the future. These are the main reasons I chose Flutter for my own project:
+ Flutter is cross-platform
Flutter successfully compiles native code for both the Android and iOS platforms. In the future, it will become the native framework of Google’s Fuchsia OS, so a project developed in Flutter will work on three platforms: iOS, Android, and Fuchsia.
+ It’s actively developed
Google is promoting and developing Flutter on a regular basis, adding new widget interfaces that allow for faster and easier development. The most important libraries are already there: Rx, flutter_redux, firebase, cached_network_image, and others. New ones appear frequently.
+ It has its own graphics engine
Unlike other cross-platform technologies, Flutter doesn’t call for native Android or iOS UI components. It uses its own graphics engine, and this is a huge advantage. With Flutter, I don’t need to fix any bugs because of device incompatibility. I don’t run into cases when an animation is great on Android but lags on iOS, for example.
+ The interface is easily divided into separate modules
The interface in Flutter is built with widget classes, and I can easily separate a module from a class to either unload the class or reuse the module as a separate class. This makes development more structured and makes reusing code easy.
Despite all the advantages of Flutter, there are drawbacks too.
– The interface must be built in the code
The UI is based on a widget class that that doesn’t support graphical interface design. While you can use a graphical editor when developing native iOS and Android apps, Flutter allows you to build interface elements only through code. This isn’t convenient, as a graphical interface allows developers to separate the interface from the logic and thus reduce code.
– There are still a few libraries
In terms of libraries and ready solutions, native languages are the leaders because they’re older. Flutter as we know it appeared only two years ago; that’s why it’s still sometimes hard to find an answer to a non-typical situation. Additionally, logs in the Flutter console aren’t always helpful.
This is why I think Flutter isn’t mature enough yet for big enterprise projects. However, it’s just perfect for small apps, MVPs, and demos, one of which I will describe in this case study.
How I approached the architecture
For my project, I used a combination of Redux and a Model–View–ViewModel (MVVM) architecture. I placed all the information responsible for the content into ViewModel classes, with the ViewModel getting data from the global State.
If the State is updated, the ViewModel is updated as well, and thus the widget also changes its appearance. The Redux architecture really helps with managing updates to a component located in a different module that doesn’t contain this particular component.
For example, if a user adds a product to a shopping cart in the highest layer of a navigation stack, the layer below will update automatically (by updating the shopping cart badge that shows the current number of items in the cart). Not only do Redux and MVVM make this possible, but it also decomposes the code perfectly.
All the content like images and titles is stored in a JSON file that’s placed in Firebase storage. As the project is launched, Firebase loads the JSON file and shows the content on the screen. The data in the JSON file has different titles for text fields, URLs for banners and images, and more.
Libraries I used for the project
These are all the libraries I used for my Flutter demo project:
cached_network_image – For uploading and caching images from the web. This library is convenient if you have a spreadsheet that loads content via a URL. Instead of loading an image each time a cell is reused, the library loads it to cache once, then loads it from there.
async – A library for handling asynchronous requests
flutter_redux – A library for the Redux architecture I described earlier
page_indicator – Unfortunately, there’s no native indicator for pageView in Flutter. Page_indicator is a third-party component that’s responsible for showing the page index.
smooth_star_rating – A UI component for rating products that allows the mobile app owner to set a rating.
badges – Adds a badge to an icon – for example, showing the number of products in a shopping cart. This library contains different types of animations for badge updates.
rflutter_alert – A library for displaying alerts and pop-ups.
firebase_core / firebase_storage – To manage and load the JSON file, I used Firebase storage, and this library connects Firebase to my project.
Challenges I faced
I faced two challenges while developing this small project. One of them was related to one of the libraries, another was an issue that made my animation look broken.
1. The page indicator challenge. As I already mentioned, I used a third-party UI component to display the page indicator on the banner carousel. However, when I implemented it, the Page_indicator placed its component right on the container with the carousel. I needed to display the page indicator below the containers with banners.
2. The animation challenge. I used a Hero widget for animating the transition between screens – in particular, between the main screen and product pages. When integrating the Hero widget, I needed to connect it to a certain component: in my case, an image.
The second screen that opens on the tap is a list. After the user scrolls the list, the image becomes invisible because it’s situated at the top of the screen. This is what makes the animation logic fail: after the user returns to the new page, this transition needs to be animated as well, but because the image isn’t visible, the animation doesn’t happen.
My solutions
These are the technical and UI decisions I made to solve these challenges.
To make sure the page indicator is placed below the banner carousel, I created another container and placed the carousel on top of it. I made this additional container transparent so that the UI remained the same. Then I attached the page indicator to the transparent container so that it was placed right where I planned it to be.
To solve the issue with the animation, I decided to place the block with the image in a header so that after a user scrolls down, the image remains visible.
In this way, I managed to preserve the animation logic that was linked to the image.
Results
As a result, I got a functioning demo project that’s flexible and works for businesses in all kinds of domains that sell products and services, from eCommerce to fitness.
I spent approximately 100 to 110 hours on this project, including the time I spent getting familiar with Dart and Flutter. As I’m an iOS developer, it took me a bit more time to understand these technologies, but Dart is rather easy for anyone who has experience developing apps for either iOS or Android.
The biggest advantage I see in Flutter is that I was able to complete the project on my own for both iOS and Android. From the business standpoint, it’s a great advantage, because it allows for having fewer team members and developing faster.
As an iOS developer, I think that Dart is still behind Swift in terms of possibilities. For example, tools like enum, switch case, and extension are more powerful in Swift. That said, Dart is still a rather powerful instrument, and I believe that in the near future, it will become one of the most popular programming languages for mobile development.