Dart Mixins Tutorial for Flutter: Getting Started

Learn about Flutter mixins, which help you implement some of the OOPs methodologies such as inheritance and abstraction in Dart. By Monikinderjit Singh.

5 (1) · 1 Review

Download materials
Save for later
Share
You are currently viewing page 2 of 2 of this article. Click here to view the first page.

Integrating Multiple Mixins

In the previous section, you created a custom mixin that will act as base screens for other screens of the applications. In this section, you’ll connect screens and use mixins to create the required output.

Open first_animation.dart file and replace //1. TODO: declare here with the following line:

with BasicPage, SingleTickerProviderStateMixin

To use multiple mixins in Flutter, you need to use commas to separate mixins.

Replace the //2. TODO: Initialize controller here with the following code:

controller =
        AnimationController(vsync: this, duration: const Duration(seconds: 10))
          ..addListener(() {
            setState(() {});
          });

Here, you initialize the animation controller. The this keyword used here is provided by SingleTickerProviderStateMixin, which provides the current context to the animation controller. Vsync keeps track of the application screen and only starts animation when the screen is displayed.

In the same file, search for //3.TODO: remove build method and remove the build code block. Because you have extended the class with the BasicPage class, the body method will be overridden and the body method present in the first_animation.dart will be used.

Now, you need to connect first_animation.dart with the start_screen. To do this, find and replace //1. TODO: Add here in start_screen.dart with the following code block:

Navigator.of(context).push<void>(
  MaterialPageRoute(
      builder: (context) => const FirstAnimationScreen()),
);

This is Navigator, which will push the FirstAnimationScreen to the UI stack. Import first_animation.dart into start_screen.dart for the code above to work.

Build and run the app. You’ll see the following output:
First part of animation mixin

You have created a mixin custom class and connected it with the application.

The next part of this section is a test for you. You’ll use the things learned in this section and complete a task.

Testing Your Knowledge

This section is a small test for you based on the things you learned in the previous sections. You need to complete the second_animation.dart file. The TODOs have been marked in the files for your ease.

If you run into difficulty, you can refer to the Test Solution given below or go through the final folder in the attached project material.

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'base_screen.dart';

class SecondAnimation extends BaseScreen {
  const SecondAnimation({Key? key}) : super(key: key);
  @override
  _SecondAnimationState createState() => _SecondAnimationState();
}

class _SecondAnimationState extends BaseState<SecondAnimation>
    with BasicPage, SingleTickerProviderStateMixin {
  Duration duration = Duration.zero;
  late Ticker ticker;

  @override
  void initState() {
    super.initState();
    ticker = this.createTicker((elapsed) {
      setState(() => duration = elapsed);
    });
  }

  @override
  void dispose() {
    ticker.dispose();
    super.dispose();
  }

  @override
  String screenName() => 'Timer screen';

  @override
  Widget fab() {
    return FloatingActionButton.extended(
      onPressed: () {
        if (!ticker.isActive) {
          ticker.start();
        } else {
          ticker.stop();
        }
      },
      label: Text((!ticker.isActive) ? 'Start Timer' : 'Stop Timer'),
      icon: Icon(
          (!ticker.isActive) ? Icons.timer_outlined : Icons.timer_off_outlined,
          color: Colors.white),
    );
  }

  @override
  Widget body() {
    return Center(
      child: Text(
        duration.inSeconds.toString(),
        style: TextStyle(
          fontSize: 220,
          color: Theme.of(context).colorScheme.primary,
        ),
      ),
    );
  }
}

Build and run the app. You’ll see the following screen:
Final part of animation

Great job! It’s important to test your newly learned skills to see whether you’re acquiring the knowledge. If you missed something, you can go back to previous sections and check what’s missing. Here’s a star badge for you:
Star badge

In the next section, you’ll learn about the role of hierarchy in mixins.

Understanding the Role of Hierarchy

An interesting thing about using multiple mixins is that the order they’re returned determines the method calling order. Here’s an example:

class A extends B with C, D{}

Hierarchy in mixins

In the class declaration above, the order they’re declared is from left to right. This can be understood by thinking of the calling data structure as a stack.

Now, look over to your project.

If you look at the first_animation.dart file, you see the following code:
extends BaseState with BasicPage, SingleTickerProviderStateMixin

According to this line, the hierarchy stack looks something like this:

Mixins in the project

This implies that if you move from left to right, the declared classes get inserted into the stack and the importance level increases. So in any function/method with the same name described in both SingleTickerProviderStateMixin and BasicPage, the one in the SingleTickerProviderStateMixin will be executed.

You now understand what mixins are in Dart, how they’re used and how they work. Next, you’ll learn why to use mixins.

Why Use Mixins?

Now that you’ve learned about mixins, it’s important to know why one would use them. Are there benefits of using mixins over other techniques, such as inheritance?

Don’t Repeat Principle: If your project uses the same code multiple times, it’s recommended to use a single code and extend it to your required classes. This also means code reusing. The use of mixins enhances code reusability.

Diamond Problem in OOPs: Using multiple inheritances often leads to the diamond problem. Mixins are not a way of using multiple inheritances in Dart; rather, they’re a way of reusing code from multiple hierarchies without using the extend keyword. When you use mixins, the mixins class is not parallel but is at the top of the class using it. Thus, the methods don’t conflict with each other and prevent the diamond problem.

The diamond problem is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?

Playing Safe With Mixins

You’ve gone through the introduction to mixins and seen their advantages. But every feature with pros has its cons, and you should know them:

  • Using multiple mixins can result in a mixins chain, which might make debugging difficult.
  • Increased dependencies.
  • High coupling. Every new feature added to the mixin class gets added to every child class.

Where to Go From Here?

You can download the complete project using the Download Materials button at the top or bottom of this tutorial.

In this article, you learned about:

  • Mixins
  • Hierarchy in Mixins
  • When and when not to use Mixins

I hope you enjoyed this article. If you want to learn more about Mixins and OOPs concepts in Dart, check out the following:

If you have any suggestions or questions or want to show off what you did to improve this project, join the discussion below.