DEV Community

Cover image for Flutter - Manage variables globally
Luciano Jung
Luciano Jung

Posted on • Updated on

Flutter - Manage variables globally

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:

class MyService {

  static final MyService _instance = MyService._internal();

  // passes the instantiation to the _instance object
  factory MyService() => _instance;

}
Enter fullscreen mode Exit fullscreen mode

The _internal method can be used to initialize variables:

  //initialize variables in here
  MyService._internal() {
    _myVariable = 0;
  }
Enter fullscreen mode Exit fullscreen mode

Now we can create a variable called _myVariable. Using get and set, we can create one-line getter and setter methods.

  int _myVariable;

  //short getter for my variable
  int get myVariable => _myVariable;

  //short setter for my variable
  set myVariable(int value) => _myVariable = value;
Enter fullscreen mode Exit fullscreen mode

No Flutter sample project without an incrementor: That's why I also created the incrementMyVariable() method to make the sample complete.

  void incrementMyVariable() => _myVariable++;
Enter fullscreen mode Exit fullscreen mode

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.

class _MyHomePageState extends State<MyHomePage> {
  MyService _myService = MyService();

  ...
}
Enter fullscreen mode Exit fullscreen mode

We can now call the increment method on the object. This is done in the setState method to update the State object properly.

  void _incrementCounter() {
    setState(() {
      _myService.incrementMyVariable();
    });
  }
Enter fullscreen mode Exit fullscreen mode

The text object to be displayed will also access the variable via the getter method.

  Text(
    '${_myService.myVariable}',
    style: Theme.of(context).textTheme.headline4,
  ),
Enter fullscreen mode Exit fullscreen mode

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.

Alt Text

main.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),
      ),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

myservice.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++;
}
Enter fullscreen mode Exit fullscreen mode

Thanks for 10000+ readers!
Buy me a sunny day if you like to support this kind of content.


You may also like

Discussion (5)

Collapse
bkmillanzi profile image
Bkmillanzi

great post... making Flutter even more interesting to learn from you guys!

Collapse
lucianojung profile image
Luciano Jung Author

Hey, thanks for your nice comment.

Collapse
glihm profile image
glihm

Very interesting to see the service pattern and singleton pattern, thank Luciano Jung!

Collapse
lucianojung profile image
Luciano Jung Author • Edited

Hey, thanks for your nice comment. The post simply shows my proof of concept with the named pattern :)

Collapse
jefrynolastname profile image
Jefry-nolastname • Edited

set myVariable(int value) => myVariable = value;
supposed to be
set myVariable(int value) => _myVariable = value;
and to use the setterjust myVariable = something in component