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

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

问题描述

我正在尝试使用.of()方法获取应用的顶级状态,类似于Scaffold.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)

此小部件创建一个主页:

This Widget creates a HomePage:

  @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';






这是由于飞镖如何解决进口问题。


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 :


  • import'relativePath / myFile.dart'

  • import'package:myApp / path2 / myFile.dart'

  • import '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 不等于相同的 IApp从 relativePath / myApp / 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

在您的情况下,您插入了小部件树和 pappage:path 中的 IApp ,但您的 IApp.of(context)使用 IAppState 在本地解析。
它们都有不同的runtimeType。因此 const TypeMatcher< IAppState>()将不匹配。并且您的函数将返回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天全站免登陆