将数据传递给StatefulWidget并在Flutter中以它的状态访问它

我在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) {
//.....
}
}

如何在_RecordPageState中访问recordObject ?

198949 次浏览

要在_RecordPageState中使用recordObject,您必须只编写小部件。Objectname如下所示

class _RecordPageState extends State<RecordPage> {
@override
Widget build(BuildContext context) {
.....
widget.recordObject
.....
}
}
class RecordPage extends StatefulWidget {
final Record recordObject;


RecordPage({Key key, @required this.recordObject}) : super(key: key);


@override
_RecordPageState createState() => new _RecordPageState(recordObject);
}


class _RecordPageState extends State<RecordPage> {
Record  recordObject
_RecordPageState(this. recordObject);  //constructor
@override
Widget build(BuildContext context) {.    //closure has access
//.....
}
}

完整的示例 < br >

你不需要使用State的构造函数来传递参数。 你可以很容易地使用widget.myField访问它们
class MyRecord extends StatefulWidget {
final String recordName;
const MyRecord(this.recordName);


@override
MyRecordState createState() => MyRecordState();
}


class MyRecordState extends State<MyRecord> {
@override
Widget build(BuildContext context) {
return Text(widget.recordName); // Here you direct access using widget
}
}

在导航屏幕时传递数据: < br >

 Navigator.of(context).push(MaterialPageRoute(builder: (context) => MyRecord("WonderWorld")));

我必须导航回到列表页面中的任何一个屏幕,但当我这样做时,我的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;
});
},

示例如下:

class nhaphangle extends StatefulWidget {
final String username;
final List<String> dshangle;// = ["1","2"];
const nhaphangle({ Key key, @required this.username,@required this.dshangle }) : super(key: key);




@override
_nhaphangleState createState() => _nhaphangleState();
}


class _nhaphangleState extends State<nhaphangle> {
TextEditingController mspController = TextEditingController();
TextEditingController soluongController = TextEditingController();
final scrollDirection = Axis.vertical;
DateTime Ngaysx  = DateTime.now();
ScrollController _scrollController = new ScrollController();


ApiService _apiService;
List<String> titles = [];


@override
void initState() {
super.initState();
_apiService = ApiService();
titles = widget.dshangle;  //here var is call and set to
}


    

在我的应用程序中,通常不是使用有状态小部件,而是在main中主要使用ChangeNotifierProvider<T>。达特,一个模型班

class FooModel extends ChangeNotifier {


var _foo = false;


void changeFooState() {
_foo = true;
notifyListeners();
}


bool getFoo () => _foo;


}

而且

var foo = context.read<FooModel>();
# or
var foo = context.watch<FooModel>();

在我的无状态小部件中。在我看来,与有状态小部件相比,这使我能够更精确地控制运行时状态更改时的重建。

配方可以在官方的文档中找到,这个概念被称为“提升状态”。

你应该使用发布/订阅机制。 我更喜欢在许多情况和语言中使用Rx。对于Dart/Flutter,这是包:https://pub.dev/packages/rxdart

例如,你可以使用BehaviorSubject小部件的发出数据,将流传递给小部件B,后者监听变化并在设置状态中应用它们 部件:< / p >
// 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
});
});
}