Flutter 颤振从不同的类访问StatefulWidget的状态类变量

Flutter 颤振从不同的类访问StatefulWidget的状态类变量,flutter,statefulwidget,Flutter,Statefulwidget,我有一个StatefulWidget类“FirstClass”,它扩展了一个状态“FirstClassState”。从一个名为“\u SecondClassState”的单独状态类中,我试图访问一个变量的值(在“\u FirstClassState”中称为“counter”) 我已经找到了解决方案,但我不确定这是否是解决问题的最佳方案。我试着研究其他类似的问题: (在StatefulWidget类中声明变量并在State类中使用“widget.”不允许我从“\u SecondClassStat

我有一个StatefulWidget类“FirstClass”,它扩展了一个状态“FirstClassState”。从一个名为“\u SecondClassState”的单独状态类中,我试图访问一个变量的值(在“\u FirstClassState”中称为“counter”)

我已经找到了解决方案,但我不确定这是否是解决问题的最佳方案。我试着研究其他类似的问题:

  • (在StatefulWidget类中声明变量并在State类中使用“widget.”不允许我从“\u SecondClassState”获取“counter”的值)
  • 我还看到其他网站建议使用GlobalKey。然而,即使这可能是一个解决方案,我没有进一步探讨这一点,因为我发现其他网站建议尽量减少使用GlobalKeys
二级飞镖:

import 'package:brew_crew/question/first_class.dart';
import 'package:flutter/material.dart';

class SecondClass extends StatefulWidget {
  @override
  _SecondClassState createState() => _SecondClassState();
}

class _SecondClassState extends State<SecondClass> {
  final FirstClass firstClass = FirstClass();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("MyApp"),
        centerTitle: true,
      ),
      body: Column(
        children: <Widget>[
          firstClass, //Displays the button to increase 'counter'
          FlatButton(
              child: Text("Submit"),
              onPressed: () {
                print(firstClass
                    .getCounter()); //I need to get the value of 'counter' here to use elsewhere
              }),
        ],
      ),
    );
  }
}
import'程序包:brew_crew/question/first_class.dart';
进口“包装:颤振/材料.省道”;
类SecondClass扩展StatefulWidget{
@凌驾
_SecondClassState createState()=>\u SecondClassState();
}
类_SecondClassState扩展状态{
final FirstClass FirstClass=FirstClass();
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“MyApp”),
标题:对,
),
正文:专栏(
儿童:[
第一类,//显示增加“计数器”的按钮
扁平按钮(
儿童:文本(“提交”),
已按下:(){
印刷品(头等)
.getCounter();//我需要在此处获取“counter”的值,以便在其他地方使用
}),
],
),
);
}
}
一等镖

import 'package:flutter/material.dart';

class FirstClass extends StatefulWidget {
  final _FirstClassState firstClassState = _FirstClassState();

  @override
  _FirstClassState createState() => firstClassState;

  int getCounter() {
    return firstClassState.counter;
  }
}

class _FirstClassState extends State<FirstClass> {
  int counter = 0;

  //Increases counter by 1
  void _increaseCounter() {
    setState(() {
      counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    //A button which increases counter when clicked
    return FlatButton.icon(
      icon: Icon(Icons.add),
      label: Text("Counter: $counter"),
      onPressed: () {
        _increaseCounter();
      },
    );
  }
}
导入“包装:颤振/材料.省道”;
类FirstClass扩展StatefulWidget{
final _firstclassstatefirstclassstate=_FirstClassState();
@凌驾
_FirstClassState createState()=>FirstClassState;
int getCounter(){
返回firstClassState.counter;
}
}
类_FirstClassState扩展了状态{
int计数器=0;
//使计数器增加1
void _increaseCounter(){
设置状态(){
计数器++;
});
}
@凌驾
小部件构建(构建上下文){
//单击时增加计数器的按钮
返回FlatButton.icon(
图标:图标(Icons.add),
标签:文本(“计数器:$Counter”),
已按下:(){
_递增计数器();
},
);
}
}
如您所见,在“FirstClass”中,我初始化了一个新的“\u FirstClassState”实例。在“getCounter()”函数中使用此函数,可以获得“counter”值


有没有比这更好的方法(例如,最佳实践、更少的代码行、更容易理解的方法等)来实现我的目标?

如果您必须从外部访问小部件的状态,那么使用
GlobalKey
绝对是推荐的方法。然而,在这种情况下,您不应该使用任何一种方法

\u SecondClassState
应包含
计数器
,您应将其与
递增计数器
函数一起作为参数传递给
一级
。如果你想增加数字,只需调用该函数

大致如下:

class SecondClass extends StatefulWidget {
  @override
  _SecondClassState createState() => _SecondClassState();
}

class _SecondClassState extends State<SecondClass> {
  int counter = 0;

  //Increases counter by 1
  void _increaseCounter() {
    setState(() {
      counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("MyApp"),
        centerTitle: true,
      ),
      body: Column(
        children: <Widget>[
          FirstClass(counter: counter, increaseCounter: _increaseCounter), //Displays the button to increase 'counter'
          FlatButton(
              child: Text("Submit"),
              onPressed: () {
                print(counter.toString()); //I need to get the value of 'counter' here to use elsewhere
              }),
        ],
      ),
    );
  }
}
class第二类扩展StatefulWidget{
@凌驾
_SecondClassState createState()=>\u SecondClassState();
}
类_SecondClassState扩展状态{
int计数器=0;
//使计数器增加1
void _increaseCounter(){
设置状态(){
计数器++;
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“MyApp”),
标题:对,
),
正文:专栏(
儿童:[
第一类(计数器:计数器,递增计数器:\ u递增计数器),//显示递增“计数器”的按钮
扁平按钮(
儿童:文本(“提交”),
已按下:(){
print(counter.toString());//我需要在此处获取“counter”的值,以便在其他地方使用
}),
],
),
);
}
}
class第一类扩展了StatefulWidget{
最终整数计数器;
最终函数递增计数器;
第一类({this.counter,this.increaseCounter});
final _firstclassstatefirstclassstate=_FirstClassState();
@凌驾
_FirstClassState createState()=>FirstClassState;
}
类_FirstClassState扩展了状态{
@凌驾
小部件构建(构建上下文){
//单击时增加计数器的按钮
返回FlatButton.icon(
图标:图标(Icons.add),
标签:文本(“计数器:${widget.Counter}”),
已按下:(){
widget.increaseCounter();
},
);
}
}

头等舱和二等舱的结构如何?在小部件树中,第二类是否位于第一类的下方或上方,或者他们是兄弟姐妹?@AshutoshSingh抱歉,我是新来的Flatter,如果这不能回答问题,请道歉。我首先加载“SecondClass”小部件,然后在“SecondClass”小部件中加载“FirstClass”小部件。所以我认为“二等舱”应该是“一等舱”的父母谢谢你的回答。我已尝试实现此功能,但出现以下错误:'方法“call”是在null上调用的。接收方:null尝试调用:call()'。函数'increaseCounter()'在'FirstClass'构造函数中作为'null'传递(但'counter'的值正确传递)。你知道为什么会这样吗?@SidharthRanjith不确定。请尝试重新启动调试过程,以上代码在我这端起作用。我发现了错误。我已将“increaseCounter()”而不是“increaseCounter”作为参数之一传递给“FirstClass”。谢谢你在这方面的帮助。出于兴趣,你能告诉我为什么这被认为比我在问题中使用的词更好吗?@SidharthRanjith啊,可以理解为什么那不起作用。一般来说,数据从pa“向下”流动
class FirstClass extends StatefulWidget {
  final int counter;
  final Function increaseCounter;

  FirstClass({this.counter, this.increaseCounter});

  final _FirstClassState firstClassState = _FirstClassState();

  @override
  _FirstClassState createState() => firstClassState;
}

class _FirstClassState extends State<FirstClass> {
  @override
  Widget build(BuildContext context) {
    //A button which increases counter when clicked
    return FlatButton.icon(
      icon: Icon(Icons.add),
      label: Text("Counter: ${widget.counter}"),
      onPressed: () {
        widget.increaseCounter();
      },
    );
  }
}