The Startup
Published in

The Startup

Reducing Boilerplate in Flutter UIs

When building mobile User Interfaces (UIs), it is common for us developers to be required to handle the same situations over and over again as we build our various screens and components. A prime example of this is if the app we are building interacts with a remote data source, as it is likely that each screen will need to show a form of loading indicator whilst a network request is taking place.

Here is where BLoC Builders come in. These are designed to respond to states yielded by BLoCs so that the UI can render accordingly (an example of using these can be seen here). We are going to build upon this concept by creating custom BLoC Builders that will handle common BLoC states and reduce our boilerplate each time.

Whilst this approach can be used for a huge variety of purposes, in this article we are going to be creating a custom builder that will help us with handling network-related properties. We will then utilize this new builder to create a basic screen that will render states from a BLoC containing simulated network functionality.

To begin tackling this, we are going to create a BaseNetworkState that our BLoC states will be able to extend. It is going to contain an isFetching property that will be used to indicate to the UI that asynchronous network calls are taking place.

We can then create a HomeState that will extend the newly created BaseNetworkState whilst adding an extra name property that our BLoC will be retrieving for us.

Now it is time to make our BLoC. This will respond to a FetchUser event, where it will initially yield a state with isFetching set to true, this will let the UI know that an asynchronous operation is taking place. The BLoC will then proceed to simulate network latency via an artificial delay (an article I wrote demonstrating how to manage multiple data sources can be found here) before finally yielding a state containing our desired name.

We can now build upon this by creating a NetworkBlocBuilder that is going to render appropriate UI components in response to our BaseNetworkState properties. In this case, it will be responsible for handling the rendering of a loading indicator when the BLoC yields a state where isFetching is true. By default we are going to show a centrally aligned CircularProgressIndicator for this, however, we are going to make this customizable by accepting this as an optional argument.

This was achieved through a simple extension of the BlocBuilderBase and will only be compatible with states that derive from BaseNetworkState.

Finally, we can create the HomeScreen that will utilize the new NetworkBlocBuilder to help us with rendering our BLoC’s state. This will now mean that despite the HomeBLoC having multiple state properties, we only have to worry about handling the name.

…and there we have it. After the user taps the button that triggers the FetchUser event, a loading indicator will be shown until the name is available without any extra work required in the HomeScreen.

It doesn’t stop here either, as this approach can be extended to be used with another fantastic feature of the BLoC library: BLoC Listeners! For example, our BaseNetworkState could contain an errorMessage property and a NetworkBlocListener would be responsible for showing appropriate error dialogs whenever there is a message present.

Thank you for reading this article, the full example can be found here.

Feel free to connect with me on LinkedIn.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Luke Greenwood

Freelance Mobile App Developer with over 4 years experience in Software Development BSc and MSc in Computer Science