Flutter:从子级检索顶级状态返回 null [英] Flutter: Retrieving top-level state from child returns 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:path
的 IApp
但您的 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屋!