Mixins in Flutter: best use cases

Grzegorz Trochimiuk
Deviniti Technology-Driven Blog
4 min readJul 9, 2020

Some developers with mobile background coming to Flutter have trouble with understanding what mixins are and when to use them. In this article, I hope to explain that in a simple way and provide examples of mixin use cases.

What is a mixin?

The best way to understand what a mixin really is is to think about it as a set of functionalities that can be added to a class. Mixins can contain both methods and variables. How to use them? That’s easy — you just need to declare them and then use the with keyword to add them to a class. There are two ways to declare a mixin in Dart.

Option 1 — using the mixin keyword:

mixin UsefulMixin {
void usefulMethod() {
// ...
}
}

class ImportantClass with UsefulMixin {}

Option 2 — deriving a mixin from a class:

class UsefulClass {
void usefulMethod() {
// ...
}
}

class ImportantClass with UsefulClass {}

This has some limitations — namely you can’t derive a mixin from a class that extends any class other than Object.

Note: This way is not recommended and can lead to some problems with your code. In fact, Dart language specifications say that it may be removed in the future. You can learn more about it here.

When to use a mixin?

Now that we know what a mixin is let’s talk about when to use it. After all, if you want to use some code from one class in another one you can always just extend it, right? Well, Jimmy, you are wrong! There are cases where you don’t want to create a base class or extend another class to get some of its functionalities. Let’s go through some examples:

Consider the following class hierarchy:

abstract class Animal {
String name;
void speak();
}

class Dog extends Animal {
@override
void speak() {
print('woof!');
}

void walk() {
// ...
}
}

class Bird extends Animal {
@override
void speak() {
print('shriek!');
}

void fly() {
// ...
}
}

class Fish extends Animal {
@override
void speak() {
print('gul gul');
}

void swim() {
// ...
}
}

class FlyingFish extends Fish {
void fly() {
// ...
}
}

Both Bird and FlyingFish can fly, but they don’t have much else in common. We would like to keep the flying implementation in one place to be able to maintain and modify it easily, but how can we accomplish that? Yes, you guessed it — mixins to the rescue!

mixin Flying {
void fly() {
// ...
}
}

class FlyingFish extends Fish with Flying {}

class Bird extends Animal with Flying {
@override
void speak() {
print('shriek!');
}
}

Flying fish and birds are great abstractions, but how about a practical, real-world example? Consider the following situation: you need to implement a feature that lets the user upload an image — either select one from the gallery or take a new one. To do that, you implement a bottom sheet that lets the user choose the image source. Here comes the tricky part: the same feature appears in multiple views in the application — in the profile screen users can upload their profile image and in the notes screen they can attach images. In which widget should you implement the code to show a bottom sheet? In both? Nope, in neither. You should use a mixin.

mixin ImagePickerSheet {
Future<File> showImagePickerSheet(BuildContext context) {
return showModalBottomSheet(
context: context,
builder: _buildBottomSheet,
);
}

Widget _buildBottomSheet(BuildContext context) {
// ...
}
}

Mixins in Flutter — other use cases

Mixins are cool, I hope we already established that. But there is one more thing you can do with a mixin — define it on a class:

class ImportantClass {
String importantVariable;

void importantMethod() {
// ...
}
}

mixin UsefulMixin on ImportantClass {
void usefulMethod() {
// ...
}
}

By doing that, you restrict where you can use your mixin to classes that extend ImportantClass, but in return, you can use variables and methods defined in ImportantClass in your mixin. This can be useful in example for creating UI related mixins that need to access something from the widget classes.

Conclusion

As you can now hopefully agree with, there is nothing scary about mixins in Flutter. In fact, they can be a very useful tool in making your codebase neat and clean. Now go and mix them into your code!

Deviniti is your guide to the universe of digital transformation and enterprise software. Check out who we are and what we do on our website.

If you want to learn more Flutter tips and tricks, make sure to check out other articles available on Deviniti Technology-Driven Blog:

--

--