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;

}

The _internal method can be used to initialize variables:

  //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.

  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.

  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.

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.

  void _incrementCounter() {
    setState(() {
      _myService.incrementMyVariable();
    });
  }

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

  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.

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

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++;
}

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


You may also like

This post is also available on DEV.