0

I am currently working on this tutorial in which transfers a variable "myVariable" an external file to another. Link: https://dev.to/lucianojung/global-variable-access-in-flutter-3ijm

I modified my code so that the variable "myVariable" is usable in the myservice.dart file, it works, but the problem is that I cannot dynamically update my text widget "widget.myVariable", it updates only when I do a "hot reaload" I think we should add a setStat, but I do not know how to implement it despite several attempts.

Thanks for your help

myservice.dart

import 'package:flutter/material.dart';
import 'main.dart';

class MyService extends StatefulWidget {
  //Passed 'myVariable' ///////////////////////////////////////////////////
  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++;
  /////////////////////////////////////////////////////
  @override
  _MyServiceState createState() => _MyServiceState();
}

class _MyServiceState extends State<MyService> {

  /* i try this but no result
   _displayCounter() {
     setState(() {
       widget.myVariable;
     });
   }
*/
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      width: 250,
      height: 90,
      child: Text(
        // '${_displayCounter()}',
        '${widget.myVariable}',
      ),
    );
  }
}

main.dart

import 'package:flutter/material.dart';
import 'myservice.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();
  _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:',
            ),
            MyService(), //myservice.dart
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
  • The MyService Widget you are using to inititalize your variable here : MyService _myService = MyService(); and the one you are using in your widget tree, both are different objects. Whenever you call a constructor eg : MyService(), it will create a completely new object with it's own properties. Try re-using the same _myService variable you inititalized in your widget tree so you will be using the same object in the widget tree for which you wrote a the setState function for. – Sarvesh Dalvi Jul 01 '21 at 18:01

1 Answers1

0

We use a singleton when we need to manage a shared resource. You can read more here.

What you are trying here, is to use the singleton class as a 'widget'.

It is evident that you are trying to use myVariable. Perhaps you can make a separate widget that meets this requirement.

1 -> Edit main.dart : I will make use of _myService object and pass it to Service() where it is supposed to show the count.

children: <Widget>[ 
  Text( 
   'You have pushed the button this many times:',
  ),

 /* Now because of setState(), the build method will be called
    as many times as the counter increases, which will call
    Service() with the MyService instance below
  */ 

Service(_myService), //  ------ service_widget.dart 
]

2 -> Leave myservice.dart as it is (as given in the tutorial).

3 -> service_widget.dart will be as follows:

import 'package:flutter/material.dart';
import './myservice.dart';

class Service extends StatelessWidget {

final MyService myService; 
Service(this.myService); // making use of MyService instance

@override
Widget build(BuildContext context) {
  return Container(
    color: Colors.yellow,
    width: double.infinity,
    child: Text(
      '${myService.myVariable}', // Access myVariable here
       textAlign: TextAlign.center,
       style: TextStyle(
         fontSize: 25,
         fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}  

Flutter App - Counter of Clicks

Now it works fine!

Though you can see the full code here, I highly recommend you play around some more.

  1. main.dart

  2. myservice.dart

  3. service_widget.dart

abdev
  • 597
  • 4
  • 17
  • Thank you so much for your job , the code work fine and your explanation are clear , but i have a question , what is the better way ? gather `service_widget.dart` and `myservice.dart ` in one file or let it like you do. –  Jul 02 '21 at 08:41
  • 1
    @igachi ```myservice.dart``` is there to supply you with that single instance and nothing more. So according to me, this class and the ```service_widget.dart``` should remain separate. Though I also welcome comments from seasoned developers. – abdev Jul 02 '21 at 08:46