Search code examples
flutterdartvariablesprovider

How to pass variables between 2 different files and manipulate them


I am learning flutter, and I would like to know how to pass a variable or a method between 2 different files (to add additional widgets). In my example, I took the code provided by flutter when we create a new project, to this code, I added a second file called "second.dart" in which I get the variable "_counter" in the file main "main.dart" which I multiply by 10.

main.dart

import 'package:flutter/material.dart';
import 'second.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 Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {

  int _counter = 0;
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @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(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
            Container(
              child: Second(),
            ),
          ],
        ),
      ),

      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}


second.dart

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

class Second extends StatefulWidget {
  @override
  _SecondState createState() => _SecondState();
}

class _SecondState extends State<Second> {
  
  int counter10 = _MyHomePageState._counter * 10;


  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      width: 200,
      height: 300,
      child: Text('My increment * 10 : $counter10 '),
    );
  }
}

however, I have this error."_MyHomePageState" is highlighted in red.

lib/second.dart:11:18: Error: Getter not found: '_MyHomePageState'. var counter10 =_MyHomePageState._counter * 10;

Thank you for your help


Solution

  • See this isn't the way how we pass variables to the other files or other widgets. To create a widget you need to choose between stateful or stateless if you want to manipulate state from inside of the Second class declare it as a stateful but in your case you need to have a stateless widget.

    For Example this:

        class Second extends StatelessWidget {
          final int counter;
        
          const Second({Key key, this.counter}) : super(key: key);
        
          @override
          Widget build(BuildContext context) {
            return  Container(
          color: Colors.red,
          width: 200,
          height: 300,
          child: Text('My increment * 10 : ${counter * 10} '));
          }
        }
    

    And Pass this variable from your first that is like this :

    import 'package:flutter/material.dart';
    import 'second.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 Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
    
      int _counter = 0;
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
      @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(
                  '$_counter',
                  style: Theme.of(context).textTheme.headline4,
                ),
                Container(
                  child: Second(counter:_counter),
                ),
              ],
            ),
          ),
    
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    }
    

    Note : You can share normal variables by referring them across classes but they shouldn't be private eg have an _ in front of them. Another thing even if you share your variable it wont have any effect on the Second Page directly as flutter doesn't know that it is changing and rather just treat it as an instance.

    You can share static data using classes: example

    class AppStrings {
    static Color appColor = Colors.blue;
    } 
    

    And later refer to it as AppStrings.appColor