我在Flutter应用程序中有两个屏幕:记录列表和创建和编辑记录的屏幕。
如果我传递一个对象到第二个屏幕,这意味着我将编辑这个,如果我传递null,这意味着我正在创建一个新项目。编辑屏幕是一个有状态的小部件,我不确定如何使用这种方法https://flutter.io/cookbook/navigation/passing-data/。
class RecordPage extends StatefulWidget {
final Record recordObject;
RecordPage({Key key, @required this.recordObject}) : super(key: key);
@override
_RecordPageState createState() => new _RecordPageState();
}
class _RecordPageState extends State<RecordPage> {
@override
Widget build(BuildContext context) {
//.....
}
}
我怎么能访问recordObject内_RecordPageState?
在我的应用程序中,我经常使用ChangeNotifierProvider<T>,而不是使用有状态的小部件。达特,一个模型班
class FooModel extends ChangeNotifier {
var _foo = false;
void changeFooState() {
_foo = true;
notifyListeners();
}
bool getFoo () => _foo;
}
and
var foo = context.read<FooModel>();
# or
var foo = context.watch<FooModel>();
在我的无状态小部件中。在我看来,与有状态小部件相比,这使我能够更精确地控制运行时状态更改时的重建。
配方可以在官方文档中找到,这个概念被称为“提升状态”。
我必须导航回到列表页面中的任何一个屏幕,但当我这样做时,我的onTap功能停止工作,导航停止。
class MyBar extends StatefulWidget {
MyBar({this.pageNumber});
final pageNumber;
static const String id = 'mybar_screen';
@override
_MyBarState createState() => _MyBarState();
}
class _MyBarState extends State<MyBar> {
final List pages = [
NotificationScreen(),
AppointmentScreen(),
RequestBloodScreen(),
ProfileScreen(),
];
@override
Widget build(BuildContext context) {
var _selectedItemIndex = widget.pageNumber;
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
elevation: 0,
backgroundColor: Colors.white,
unselectedItemColor: Colors.grey.shade700,
selectedItemColor: Color(kAppColor),
selectedIconTheme: IconThemeData(color: Color(kAppColor)),
currentIndex: _selectedItemIndex,
type: BottomNavigationBarType.fixed,
onTap: (int index) {
setState(() {
_selectedItemIndex = index;
});
},
你应该使用Pub/Sub机制。
我更喜欢在许多情况和语言中使用Rx。对于Dart/Flutter,这是一个包:https://pub.dev/packages/rxdart
例如,您可以使用一个BehaviorSubject从小部件a发出数据,将流传递给小部件B,后者侦听更改并在setState中应用它们。
部件:
// initialize subject and put it into the Widget B
BehaviorSubject<LiveOutput> subject = BehaviorSubject();
late WidgetB widgetB = WidgetB(deviceOutput: subject);
// when you have to emit new data
subject.add(deviceOutput);
小部件B:
// add stream at class level
class WidgetB extends StatefulWidget {
final ValueStream<LiveOutput> deviceOutput;
const WidgetB({Key? key, required this.deviceOutput}) : super(key: key);
@override
State<WidgetB> createState() => _WidgetBState();
}
// listen for changes
@override
void initState() {
super.initState();
widget.deviceOutput.listen((event) {
print("new live output");
setState(() {
// do whatever you want
});
});
}