Here's my code:
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),
),
);
}
}
In the code above, when the FAB is clicked, MaterialApp
should rebuild, and the primary color will switch between blue and red.
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:
App
class, or the variable) is moved to another file;MyHomePage
and _MyHomePageState
) is moved to another file;So it looks like the GlobalKey.currentState
only work when everything involving this GlobalKey is in the same file.
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.
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.
That is due to how dart import works.
In dart, there is two way to import sources :
The thing is, they are not compatible with each others. Both these imports will have a different runtimeType
.
But how is that a problem ? I never used relative import
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
.
So, how do I solve the problem ?
There are multiple solutions :
App
should be inside the same file. (That's the recommended thing in dart)App
into it's own file. And import it everywhere using absolute imports.GlobalKey
to begin with. As your use case is definitely in the scope of InheritedWidget
. If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With