您的代码中有两个问题:
-
在主体中使用异步方法initState()
see here https://flutter.institute/run-async-operation-on-widget-creation/欲了解详情
-
在初始化程序中使用实例数据
看here https://stackoverflow.com/questions/50145150/error-only-static-members-can-be-accessed-in-initializers-what-does-this-mean欲了解详情
接下来是对代码的非常基本的重写,并进行了最少的更正。
数据映射从模拟后端加载,并在内部更新PageOne
并打印到控制台PageTwo
onTap 回调。
请注意,我已经更改了实例变量Data
to data
遵守有效飞镖 https://www.dartlang.org/guides/language/effective-dart/style#do-name-other-identifiers-using-lowercamelcase指导方针。
请注意,要点没有正确解决后端服务与共享首选项的同步:这可能需要在最终产品中考虑。
我只是评论了让您的代码正常工作所需的条件:
如果您的系统的复杂性以及与外部 API 的关系开始增长,那么可能值得考虑 Bloc 架构。
import 'package:flutter/material.dart';
void main() => runApp(new MainApp());
// Mock up of an async backend service
Future<Map<String, dynamic>> getData() async {
return Future.delayed(Duration(seconds: 1), () => {'prop1': 'value1'});
}
class PageOne extends StatelessWidget {
final Map<String, dynamic> data;
PageOne({Key key, this.data}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: const Text('update preferences'),
onPressed: () {
data['prop2'] = 'value2';
},
),
);
}
}
class PageTwo extends StatelessWidget {
final Map<String, dynamic> data;
PageTwo({Key key, this.data}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: const Text('Got It!'),
onPressed: () {
print("data is now: [$data]");
},
),
);
}
}
class MainApp extends StatefulWidget {
@override
_MainAppState createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
//Map<String, dynamic> Data;
Map<String, dynamic> data;
/*
StartFunc() async {
Data = await getData();
setState(() {});
}
*/
@override
void initState() {
//StartFunc();
super.initState();
getData().then((values) {
setState(() {
data = values;
});
});
}
/*
PageOne(data:data) is an invalid value for an initializer:
there is no way to access this at this point.
Initializers are executed before the constructor,
but this is only allowed to be accessed after the call
to the super constructor.
*/
/*
var _pages = [
PageOne(data:data),
PageTwo(),
];
*/
Widget getPage(int index) {
switch (index){
case 0:
return PageOne(data:data);
break;
case 1:
return PageTwo(data:data);
break;
default:
return PageOne();
break;
}
}
int _currentIndex = 0;
onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
@override
Widget build(BuildContext context) {
/*
return _currentIndex == 2
? PageTwo()
: Scaffold(
I use a MaterialApp because of material widgets (RaisedButton)
It is not mandatory, but it is mainstream in flutter
*/
return MaterialApp(
title: 'My App',
home: Scaffold(
appBar: AppBar(title: Text("My App Bar")),
body: getPage(_currentIndex),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.first_page), title: Text('')),
BottomNavigationBarItem(
icon: Icon(Icons.last_page), title: Text('')),
],
onTap: onTabTapped,
currentIndex: _currentIndex,
),
));
}
}