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