Did you also face the problem that you want to access variables across widgets in your Flutter project? And this in a simple and manageable way?
For me, service classes have become the standard solution due to their simplicity of implementation!
In this post you will learn how to set up a simple sevice class in Flutter, how to apply the singleton pattern and how to create easy getter and setter methods.
Buy me a sushi roll if you like to support this kind of content.
So, you have your stateful widget and you want to use a variable not locally, but globally in Flutter. Why not set up a service class that manages this variable.
myservice.dart -> MyService
Using the singleton pattern, the MyService class should manage an object _instance and return it when an object is created. This is done with this code snippet:
dart
class MyService {
static final MyService _instance = MyService._internal();
// passes the instantiation to the _instance object
factory MyService() => _instance;
}
The _internal method can be used to initialize variables:
dart
//initialize variables in here
MyService._internal() {
_myVariable = 0;
}
Now we can create a variable called _myVariable. Using get and set, we can create one-line getter and setter methods.
dart
int _myVariable;
//short getter for my variable
int get myVariable => _myVariable;
//short setter for my variable
set myVariable(int value) => _myVariable = value;
No Flutter sample project without an incrementor: That's why I also created the incrementMyVariable() method to make the sample complete.
dart
void incrementMyVariable() => _myVariable++;
Main.dart -> _MyHomePageState
The service class is now finished and can be implemented. To use it in an existing widget, we get the instance of the service class just as we would create a new instance.
dart
class _MyHomePageState extends State<MyHomePage> {
MyService _myService = MyService();
...
}
We can now call the increment method on the object. This is done in the setState method to update the State object properly.
dart
void _incrementCounter() {
setState(() {
_myService.incrementMyVariable();
});
}
The text object to be displayed will also access the variable via the getter method.
dart
Text(
'${_myService.myVariable}',
style: Theme.of(context).textTheme.headline4,
),
This is how the classic Flutter Demo Counter with an integrated service is created!
You can see the complete code by simply scrolling down to the bottom.
Since there' s often not only one right solution, I would be interested to know what your alternative solution would look like?Feel free to comment bellow.
main.dart
dart
import 'package:exampleapp/myservice.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Service Demo App'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
MyService _myService = MyService();
void _incrementCounter() {
setState(() {
_myService.incrementMyVariable();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${_myService.myVariable}',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
myservice.dart
dart
class MyService {
static final MyService _instance = MyService._internal();
// passes the instantiation to the _instance object
factory MyService() => _instance;
//initialize variables in here
MyService._internal() {
_myVariable = 0;
}
int _myVariable;
//short getter for my variable
int get myVariable => _myVariable;
//short setter for my variable
set myVariable(int value) => myVariable = value;
void incrementMyVariable() => _myVariable++;
}
🥳Thanks for 10000+ readers!🎉
Buy me a sunny day if you like to support this kind of content.
Top comments (7)
Thank you very much you've opened to me new doors
set myVariable(int value) => myVariable = value;
supposed to be
set myVariable(int value) => _myVariable = value;
and to use the setterjust myVariable = something in component
great post... making Flutter even more interesting to learn from you guys!
Hey, thanks for your nice comment.
Very interesting to see the service pattern and singleton pattern, thank Luciano Jung!
Hey, thanks for your nice comment. The post simply shows my proof of concept with the named pattern :)
is it possible to use change notifier type with singleton class.. Actually i am using singleton class.. When data is updated of singleton class i have to notify some widget..
(without provider)
Some comments have been hidden by the post's author - find out more