简体   繁体   中英

How do i use flutter variables from main.dart in other screen.dart files in the same lib folder?

I wanted to create an app that randomly generates my lucky number when i press floatingActionButton. I wanted to do it within 2 dart files.. let me show you the code in dart.main and first_screen.dart.

dart.main


import 'package:demo/app_screens/first_screen.dart';
import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(
  debugShowCheckedModeBanner: false,
  home: MyFlutterApp()
));

class MyFlutterApp extends StatefulWidget {
  @override
  _MyFlutterAppState createState() => _MyFlutterAppState();
}

class _MyFlutterAppState extends State<MyFlutterApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.yellow,
        centerTitle: true,
        title: Text('My first App',style: TextStyle(color: Colors.black, fontSize: 25.0),),
      ),
      body: FirstScreen(),
     floatingActionButton: FloatingActionButton(
        onPressed: (){
          setState(() {
          int thatNum = generateLuckyNumber();
        });},
        child: Icon(Icons.add),
     ),
    );
  }
}

and first_screen.dart in the lib/screens directory

import 'dart:math';

import 'package:flutter/material.dart';

class FirstScreen extends StatefulWidget{
  @override
  _FirstScreenState createState() => _FirstScreenState();
}

class _FirstScreenState extends State<FirstScreen> {
  @override
  Widget build(BuildContext context) {
    return Material(color: Colors.lightBlue,
      child: Center(
        child: Text('My lucky number is ${thatNum}',style: TextStyle(
            fontSize: 28,color: Colors.black,backgroundColor:Colors.white)),
      ),
    );
  }


}

int generateLuckyNumber() {
  var random= Random();
  int luckyNumber= random.nextInt(10);
  return luckyNumber;
}

I would like to use the varibale thatNum declared in main.dart file in the first_screen.dart file.. How do you do that?

The easiest way to do this, pass the thatNum in FirstScreen constructor. Do the required changes given below

class _MyFlutterAppState extends State<MyFlutterApp> {
  int thatNum;   // <- declare thatNum in the class
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.yellow,
        centerTitle: true,
        title: Text('My first App',style: TextStyle(color: Colors.black, fontSize: 25.0),),
      ),
      body: FirstScreen(thatNum:thatNum),  // <-- pass thatNum in constructor
     floatingActionButton: FloatingActionButton(
        onPressed: (){
          setState(() {
          thatNum = generateLuckyNumber();  /* <- generateLuckyNumber and assign to thatNum */
        });},
        child: Icon(Icons.add),
     ),
    );
  }
}

In the FirstScreen declare thatNum

class FirstScreen extends StatefulWidget{
  final thatNum;   // <- declare thatNum
  FirstScreen({this.thatNum});
  @override
  _FirstScreenState createState() => _FirstScreenState();
}

In _FirstScreenState check whether the widget.thatNum is null or not. If it is null assign Loading text or show thatNum if not widget.thatNum is not null.

class _FirstScreenState extends State<FirstScreen> {
  @override
  Widget build(BuildContext context) {
    return Material(color: Colors.lightBlue,
      child: Center(
        child: Text('My lucky number is ${widget.thatNum??"Loading"}',style: TextStyle(
            fontSize: 28,color: Colors.black,backgroundColor:Colors.white)),
      ),
    );
  }
}

Note: You can also use state management solution, but the above solution solves the issue easily. Still, you can check state management solution here

You can do this thing in two ways:

  1. Pass the variables in dependency of FirstScreen.
  2. Use InheritedWidget.

1. Pass the variables in dependency of FirstScreen.

body: FirstScreen(thatNum), // in Scaffold of main.dart file.

Use it like:

class FirstScreen extends StatefulWidget{
  final thatNum;
  FirstScreen(this.thatNum);
  @override
  _FirstScreenState createState() => _FirstScreenState();
}

class _FirstScreenState extends State<FirstScreen> {
  @override
  Widget build(BuildContext context) {
    return Material(color: Colors.lightBlue,
      child: Center(
        child: Text('My lucky number is ${widget.thatNum} ??"Loading"}',style: TextStyle(
            fontSize: 28,color: Colors.black,backgroundColor:Colors.white)),
      ),
    );
  }
}

2. Use InheritedWidget.

Create an InheritedWidget as follows.

class MyInheritedWidget extends InheritedWidget {
  const MyInheritedWidget({
    Key key,
    @required this.thatNum,
    @required Widget child,
  }) : assert(color != null),
       assert(child != null),
       super(key: key, child: child);

  final thatNum;

  static MyInheritedWidget of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
  }

  @override
  bool updateShouldNotify(MyInheritedWidget old) => thatNum!= old.thatNum;
}

Change: body: FirstScreen(), to: body: MyInheritedWidget(child: FirstScreen(), thatNum:thatNum),

Now all the decendent of MyInheritedWidget will be able to access thatNum by using context like:

class _FirstScreenState extends State<FirstScreen> {
  @override
  Widget build(BuildContext context) {
    final thatNum = MyInheritedWidget.of(context).thatNum;
    return Material(color: Colors.lightBlue,
      child: Center(
        child: Text('My lucky number is $thatNum ??"Loading"}',style: TextStyle(
            fontSize: 28,color: Colors.black,backgroundColor:Colors.white)),
      ),
    );
  }
}

If you have a child Widget that needs thatNum and that child widget doesn't need to pass thatNum to any further widget then thatNum should be passed in dependency.

If you have a long hierarchy of Widget that need this data then InheritedWidget must be used to avoid passing data in each and every child's constructor.

I hope this helps, in case of any doubt please comment. If this answer helps you then please accept and up-vote it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM