Flutterexperts

Empowering Vision with FlutterExperts' Expertise
Inheritance with Mixin in Flutter

What is Inheritance? Let’s assume that there is a functionality that is used on every screen of the app or in a majority of screens of the app, what you will prefer to implement this functionality writing code once or making a method with the required parameters and using that method in every screen by calling it simple. Of course, we would prefer code reusability, that’s called inheritance.

Now, if there is a class that requires more than one class property, it is not possible to extend that class to more than one class. So to avoid such inheritance ambiguity we require mixins. Mixins are really great in dart as they provide us flexibility for code reusability.

mixins are normal classes whose method can be used in another class without extending the class. In dart, we can do this by using the keyword with.

In this blog, we shall learn how we build a mixin in a flutter that records the time spend on a particular screen. This functionality is very important if we are using analytics in our app to track the user’s behavior.


Why we require a mixin to do this? Let’s say there are 50 screens in an app and we want to implement a timer in every screen then we need to write code for the timer on every screen if we do such a thing then it is not a good practice as we are using the same code in every screen again and again. So we can create a mixin for it.

Create a mixin named TimerMixin .

mixin TimerMixin {}

We will create two methods startTimer and disposeTimer which will start the timer and stop the timer.

startTimer() {
Timer.periodic(Duration(seconds: 1), (Timer timer) {
timerData.clear();
timerData.add(timer.tick.toInt());
});
return timerData;
}

To keep on increasing the duration value every second, we can use the Timer periodic property to execute a reoccurring function. It takes a duration property and a callback that takes Timer . Inside the callback, we can add the timer tick into a List.

timerData.clear(); why we need this?

Let’s assume that the user keeps the screen open for a longer period of time in this case the List size will be increased a lot, so to maintain the space complexity we are removing all the elements from the List and storing the next element in it.

void disposeTimer() {
hoursStr =
((timerData[0] / (60 * 60)) % 60).floor().toString().padLeft(2, "0");

minutesStr = ((timerData[0] / 60) % 60).floor().toString().padLeft(2, "0");
secondsStr = (timerData[0] % 60).floor().toString().padLeft(2, "0");
print("$hoursStr:$minutesStr:$secondsStr");
}

disposeTimer the method will be executed when the screen disposes of it. This method will take the integer stored in the timerData and parse it to an hour, min, and second.

mixin. dart:

import 'dart:async';mixin TimerMixin {
String hoursStr = '00';
String minutesStr = '00';
String secondsStr = '00';
List<int> timerData = [];

startTimer() {
Timer.periodic(Duration(seconds: 1), (Timer timer) {
timerData.clear();
timerData.add(timer.tick.toInt());
});
return timerData;
}

void disposeTimer() {
hoursStr =
((timerData[0] / (60 * 60)) % 60).floor().toString().padLeft(2, "0");

minutesStr = ((timerData[0] / 60) % 60).floor().toString().padLeft(2, "0");
secondsStr = (timerData[0] % 60).floor().toString().padLeft(2, "0");
print("$hoursStr:$minutesStr:$secondsStr");
}
}

Now create a state full class. To use mixin in it we will use with keyword.

class DemoPage extends StatefulWidget {
const DemoPage({Key key}) : super(key: key);

@override
_DemoPageState createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> with TimerMixin {

@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Hello"),
),
);
}
}

We can now use all the methods TimerMixin inside the DemoPage. Inside the initState and dispose the method we can use them.

@override
void initState() {
startTimer();
super.initState();
}

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

main. dart:

import 'package:flutter/material.dart';
import 'package:minin_demo/mixin.dart';

void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
color: Colors.red,
child: Text(
"Navigate",
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DemoPage(),
),
);
},
),
),
);
}
}

class DemoPage extends StatefulWidget {
const DemoPage({Key key}) : super(key: key);

@override
_DemoPageState createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> with TimerMixin {
@override
void initState() {
startTimer();
super.initState();
}

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

@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Hello"),
),
);
}
}

App Flow:

The home page will contain a simple button in the center, on pressing it the user will be navigated to the new page, and on navigating back to the home page from the new page the duration spent by the user on the new page will be displayed on the run console.


🌸🌼🌸 Thank you for reading. 🌸🌼🌸

Feel free to connect with us:
And read more articles from FlutterDevs.com

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app 987tr project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, Twitter, and LinkedIn for any flutter-related queries.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences!.

Leave comment

Your email address will not be published. Required fields are marked with *.