为什么从其他文件访问时Flutter GlobalKey的currentState为NULL [英] Why Flutter GlobalKey's currentState is NULL when accessed from other file

查看:1731
本文介绍了为什么从其他文件访问时Flutter GlobalKey的currentState为NULL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码:

import 'package:flutter/material.dart';

void main() {
  runApp(new MyStatefulApp(key: App.appStateKey));
}

/// Part [A]. No difference when appStateKey is defined as variable.
class App {
  static final GlobalKey<MyAppState> appStateKey = new GlobalKey<MyAppState>();
}

/// Part [B] 
class MyStatefulApp extends StatefulWidget {
  MyStatefulApp({Key key}) :super(key: key);

  @override
  MyAppState createState() => new MyAppState();
}

class MyAppState extends State<MyStatefulApp> {

  int _counter = 0;

  add() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "App",
      theme: new ThemeData(
        primarySwatch: _counter % 2 == 0 ? Colors.blue : Colors.red,
      ),
      home: new MyHomePage(),
    );
  }
}

/// Part [C] 
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text("Main"),      ),
      body: new FlutterLogo(),
      floatingActionButton: new FloatingActionButton(
        onPressed: () {
          App.appStateKey.currentState.add(); // (X)
        },
        tooltip: "Trigger color change",
        child: new Icon(Icons.add),
      ),
    );
  }
}

在上面的代码中,单击FAB时,应重新构建MaterialApp,并且原色将在蓝色和红色之间切换.

In the code above, when the FAB is clicked, MaterialApp should rebuild, and the primary color will switch between blue and red.

事实上,代码起作用了,直到我尝试将代码的各个部分拆分为不同的文件.在以下情况下,第(X)行上的App.appStateKey.currentState将变为null:

In fact, the code worked, until I attempted to split the portions of the code to different files. App.appStateKey.currentState on line (X) will be become null when:

  • A部分(App类或变量)被移至另一个文件;
  • C部分(MyHomePage_MyHomePageState)已移至另一个文件;
  • A部分和C部分移至另一个文件
  • Part A (The App class, or the variable) is moved to another file;
  • Part C (MyHomePage and _MyHomePageState) is moved to another file;
  • Part A and C are moved to another file

因此,看起来GlobalKey.currentState仅在涉及此GlobalKey的所有文件都在同一文件中时起作用.

So it looks like the GlobalKey.currentState only work when everything involving this GlobalKey is in the same file.

文档仅声明(1) there is no widget in the tree that matches this global key, (2) that widget is not a StatefulWidget, or the associated State object is not a subtype of T.currentState将为空,而没有声明所有内容都必须在同一文件中.

The doc only states that currentState will be null when (1) there is no widget in the tree that matches this global key, (2) that widget is not a StatefulWidget, or the associated State object is not a subtype of T. It doesn't state that everything has to be in the same file.

将类分割成文件可能不是"Dart方式",但是我认为它应该可以正常工作(它们都是公共的).因此,这使我感到困惑,并且我怀疑是否偶然发现了我不知道的某些Flutter功能.谢谢.

Breaking classes into files may not be "the Dart way", but I assume it should work anyhow (they're all public). So this puzzles me, and I suspect if I have stumbled upon certain Flutter feature that I am not aware of. Thanks.

推荐答案

这是因为dart导入的工作原理.

That is due to how dart import works.

在dart中,有两种导入源的方法:

In dart, there is two way to import sources :

  • 导入'./relative/path.dart'
  • 导入"myApp/absolute/path.dart"

问题是,它们彼此不兼容.这两种导入将具有不同的runtimeType.

The thing is, they are not compatible with each others. Both these imports will have a different runtimeType.

但这是一个问题吗?我从未使用相对导入

这是一个问题,因为在某些情况下,您隐式地使用相对导入":使用foo.dart inside foo.dart中定义的类A时.

That's a problem, because in some situations you implicitly use "relative imports" : When using a class A defined in foo.dart inside foo.dart.

那么,我该如何解决该问题?

有多种解决方案:

  • 所有与类App相关的内容都应位于同一文件内. (这是飞镖推荐的东西)
  • App提取到它自己的文件中.并使用绝对导入将其导入任何地方.
  • 请勿使用GlobalKey开始.因为您的用例肯定在InheritedWidget的范围内.
  • Have everything related to your class App should be inside the same file. (That's the recommended thing in dart)
  • Extract App into it's own file. And import it everywhere using absolute imports.
  • Don't use GlobalKey to begin with. As your use case is definitely in the scope of InheritedWidget.

这篇关于为什么从其他文件访问时Flutter GlobalKey的currentState为NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆