Flutter:从子级检索顶级状态返回 null [英] Flutter: Retrieving top-level state from child returns null

查看:14
本文介绍了Flutter:从子级检索顶级状态返回 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用类似于 Scaffold.of() 函数的 .of() 方法获取应用程序的顶级状态.这是(精简的)代码:

I'm trying to obtain the top-level state of my app using a .of()-method, similar to the Scaffold.of() function. This is the (stripped down) code:

class IApp extends StatefulWidget {    
  @override
  IAppState createState() => new IAppState();

  static IAppState of(BuildContext context) =>
    context.ancestorStateOfType(const TypeMatcher<IAppState>());
}

使用runApp(new IApp)启动应用

The app is started using runApp(new IApp)

此小部件创建主页:

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      // ommitted: some localization and theming details
      home: new HomePage(),
    );
  }

然后,我尝试从 HomePage(一个 StatefulWidget 本身)访问 State:

Then, I try to access the State from the HomePage (a StatefulWidget itself):

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      // ommited: some Scaffold properties such as AppBar
      // runtimeType not actual goal, but just for demonstration purposes
      body: new Text(IApp.of(context).runtimeType.toString()),
    );
  }

奇怪的是,当我将 HomePage 的代码与 IApp 放在同一个文件中时,代码可以工作,但只是作为一个额外的类.但是,当我将 HomePage 放在单独的文件中(main.dart 和 homepage.dart 相互导入)时,IApp.of(context) 的返回值为 null.

The strange this is, the code works when I place the code for HomePage in the same file as the IApp, but just as an extra class. However, when I place HomePage in a separate file (main.dart and homepage.dart importing each other), the return value of IApp.of(context) is null.

这是什么原因?我该如何解决?

What causes this? And how can I fix it?

推荐答案

TDLR: 导入文件只使用

import 'package:myApp/path/myFile.dart';

从不与

import './myFile.dart';

<小时>

这是由于 dart 解析导入的方式.


This is due to how dart resolves imports.

您可能只有一个源文件,但在构建过程中,会有某种重复.

You may have a single source file, but during builds, there is some kind of duplicates.

假设您正在开发myApp".要导入文件,您可以同时执行:

Let's say you're working on 'myApp'. To import a file, you could do both :

  • 导入'relativePath/myFile.dart'
  • import 'package:myApp/path2/myFile.dart'

您会认为它们指向同一个文件,对吗?但不是.其中之一将指向原始来源.而另一个将指向用于构建的临时文件.

You'd think that they point to the same file right? But no. One of them will point to the original source. While the other one will point to a temporary file used for the build.

当您开始混合两种解决方案时,问题就来了.因为对于编译器来说,这两个文件不同.这意味着从 package:myApp/IApp 导入的 IApp 不等于从 relativePath/myApp/IApp<导入的同一个 IApp/代码>

The problem comes when you start to mix both solutions. Because for the compiler, these two files are different. Which means that IApp imported from package:myApp/IApp is not equal to the same IApp imported from relativePath/myApp/IApp

就您而言,您在小部件树中插入了来自 pakage:pathIApp 但您的 IApp.of(context) 使用 IAppState 本地解析.它们都有不同的 runtimeType.因此 const TypeMatcher() 将不匹配.你的函数将返回 null.

In your case, you inserted in your widget tree an IApp from pakage:path but your IApp.of(context) use IAppState resolved locally. They both have a different runtimeType. Therefore const TypeMatcher<IAppState>() won't match. And your function will return null.

有一种非常简单的方法可以测试这种行为.创建一个仅包含

There's an extremely easy way to test this behavior. Create a test.dart file containing only

class Test {
}

然后在您的 main.dart 中添加以下导入:

then in your main.dart add the following imports :

import 'package:myApp/test.dart' as Absolute;
import './test.dart' as Relative;

您最终可以通过执行以下操作来测试:

You can finally test this by doing :

new Relative.Test().runtimeType == new Absolute.Test().runtimeType

剧透:结果是假的

这篇关于Flutter:从子级检索顶级状态返回 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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