Mixins and Base Classes : A recipe for success in Flutter
When developing an app with multiple screens, we tend to reutilize the same piece of code over many classes: showing error messages, using the same page layout and wiring up some dependencies like a Bloc. All this could be solved if we are using an
abstract base class, however, what if we have a set of features/classes that we want to use? Since a class can’t be a child of more than one class, should we create different base classes, as much as the number of combinations that we have? That’s why we have
Mixins and Base Classes: An introduction
Mixins let us add a set of “features” to a class without using parent-child hierarchy, allowing us to have in the same class one parent and multiple mixing. As such, since it’s not a parent of our class,
mixins don’t allow any declaration of constructors. You can read more about them in this article by Romain Rastel with the caveat that Dart 2 now has the
mixin keyword, as seen in the documentation.
But how do
mixins work? Let’s take as an example an
We can use this class as a parent using the
extend keyword, such as:
With this, we can initialise the class and call the parent’s method
But what if we want to add new features to
Mike? What if Mike is a coder and we want a
code function that can be used in other class, but is notused by all
mixins save that problem.
First, we need to create a
mixin class and expose the new methods we want to use.
With the keyword
with, we can add this “feature” to our
And, as with the parent, we can call all the functions that we created in
Now every class that uses the
Coder can effectively code. However, this poses a problem: this means that if we have a parent class
Animal that has a child
Squirrel, we can also have a
Squirrel that can
code()! To prevent this, we can “lock” the usage of the
mixin to a class and all classes that inherited from it with the keyword
This also gives us a powerful tool: we can now override methods that were set in the
Person class to add or change functionality.
super.think() ensures that we are still calling the code that was defined in
Person. The above code gives us the following output for the method
By grasping the concepts of both
base classes and
mixins we can now apply them to our Flutter apps.
Mixins and Base Classes: A practical Flutter Example
How can we apply this in our Flutter apps?
Take as an example the following two screens:
[image:767784E9-572B-4E8A-9F36-3E83DDB5FBAC-72574-0000355858EF6919/Simulator Screen Shot - iPhone XR - 2019-05-06 at 19.35.42.png] [image:4D5FD1AB-0DBB-4FFE-9177-69E353B27E85-72574-00003558593DD800/Simulator Screen Shot - iPhone XR - 2019-05-06 at 19.35.53.png]
Our app has several screens with the layout shown above. Instead of copying and pasting the appbar and the background for each screen, we can solve our problem using
mixins. Let’s focus on the second one.
First, since in both cases we have a screen title defined, we are going to create a
base class that has a method to provide our screen name. Second, we choose to apply these
mixins only in
StatefulWidgets, however, since we already have a class that
extends StatefulWidget, we can state that our
mixin is only going to be applied to classes that extend
Now we can create our
BasicPageMixin, where we define the background and appbar of our page.
Since the method
body() doesn’t have a body, each class that uses this
mixin must implement it, ensuring that we don’t forget to add a body to our page.
In the screenshot above, we see a
FloatingActionButton, but we may not need it for every screen, so how can we define it? By declaring a new method,
fab() that by default returns a
Container. If a class needs to add a
FloatingActionButton, they can override this method.
With this set, we can now create a new page with this
mixin and our
And with this, we now only have to declare a
body() widget to be used in each screen, saving us a few dozens of lines of code.
As a new feature, some of our screens will make API calls and we need to display an error message in the form of a Snackbar. Additionally, we decide to use the BLoC architecture in which we need to inject a new bloc when each page is created. These two problems will need the following steps:
- Change our
BaseStateso that it has access to a
blocand add it to the
- Create a new
mixinthat let us display errors messages sent by the
blocin the page using a Snackbar
BaseBloc we are just exposing a
Sink and a
Stream in order to relay error messages.
Since we don’t want any other interactions with the bloc, our
HomeBloc will just extend this class
To inject the bloc into our
BasePage classes, we need to make some amendments to our class, with one of them being making our class dependant of the type of bloc it has. In order to do that, we use
Bloc reference as a generic in the class statement.
This way, our
BaseState can access the correct bloc type using
As for the
BaseState, we are going to declare a
scaffoldKey to be used with the
ScaffoldWidget so that we can show the Snackbar.
As seen before, one of the curious properties of mixing is that if they are “linked” to a class, they can
override its methods. This is useful since in our
StatefulWidget we can
listen do the
streams in the
initState method. As such, to show the error messages, we can create a
mixin that overrides the
initState method and provides methods to show the error Snackbar with the correct message.
mixins aren’t as constrained as a parent class, which we can only have one, so we can add it to our
And there we go!
abstract classes to reuse code throughout our application.
Maybe we don’t need to do a base UI for our app, but we can use
mixins like the
ErrorHandlingMixin to provide error feedback to the user, loading screens and showing a “App is Offline” screen.
However, creating both base classes and
mixins is a process that needs some deliberation, else we might face a “Deadly Diamond of Death”, in which when calling one method that is declared in both base classes and
mixins, the compiler doesn’t know which one to choose. You can read more about it in Shubham Soni ’s article about
mixins in Flutter.