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:
- Part A (The
App
class, or the variable) is moved to another file;
- Part C (
MyHomePage
and _MyHomePageState
) is moved to another file;
- Part A and C are 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.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…