在 Flutter 中从 SecondScreen 调用 FirstScreen 的设置状态
Call set state of FirstScreen from SecondScreen in Flutter
我在 flutter 中有两个名为 'FirstScreen' 的屏幕,其中包含订单列表和 'SecondScreen' 用于某些操作。
我想在 'SecondScreen' 弹出时调用 'FirstScreen' 的设置状态,以便 'FirstScreen' 将重新加载挂单列表
SecondScreen 将接受或拒绝订单,FirstScreen 应从服务器重新加载数据,这是由 FirstScreen 中的方法 getOrders() 调用的。
首屏代码
import 'package:flutter/material.dart';
import 'package:nobleappshop/model/jobOrderItem.dart';
import 'package:nobleappshop/screens/SeconScreen.dart';
import 'package:nobleappshop/constants/constants.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class FirstScreen extends StatefulWidget {
@override
FirstScreenState createState() => FirstScreenState();
}
class FirstScreenState extends State<FirstScreen> {
Future<List<JobOrders>> _getPendingOrder() async {
var data = await http.get("$ApiServer/JobOrders/smOrdersPending");
var jsonData = json.decode(data.body);
List<JobOrders> joborderitemlist = [];
for (var i in jsonData) {
JobOrders jobOrders = JobOrders(
Eid: i["Eid"],
Uid: i["Uid"],
Name: i["Name"],
Contact: i["Contact"].toString(),
OrderStat: i["OrderStat"],
);
joborderitemlist.add(jobOrders);
}
return joborderitemlist;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('FirstScreen'),
),
body: FutureBuilder(
future: _getPendingOrder(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data.length <= 0) {
return Container(
child: Center(
child: Text('You have not made any orders yet...'),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return OrdersListWidget(
Eid: snapshot.data[index].Eid,
Uid: snapshot.data[index].Uid.toString(),
Name: snapshot.data[index].Name.toString(),
Contact: snapshot.data[index].Contact.toString(),
Status: snapshot.data[index].OrderStat.toString(),
);
},
);
}
} else {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
}
},
),
);
}
}
class OrdersListWidget extends StatelessWidget {
int Eid;
String Uid;
String Name;
String Contact;
String Status;
OrdersListWidget(
{@required this.Eid,
@required this.Uid,
@required this.Name,
@required this.Contact,
@required this.Status});
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
ListTile(
leading: Text('#$Eid'),
title: Text(Name),
subtitle: Text(Contact),
trailing: Text(Status),
onTap: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: SecondScreen(OrderId: Eid),
),
),
);
},
),
Divider(),
],
);
}
}
第二屏代码
import 'package:flutter/material.dart';
import 'package:nobleappshop/model/orderItem.dart';
import 'package:http/http.dart' as http;
import 'package:nobleappshop/widgets/iconTextWidget.dart';
import 'package:nobleappshop/widgets/scOrderItems.dart';
import 'package:nobleappshop/constants/constants.dart';
class SecondScreen extends StatefulWidget {
int OrderId;
SecondScreen({@required this.OrderId});
@override
_SecondScreenState createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
Future<http.Response> _updateJobOrder() async {
//Run Update code here
}
double totalAmount = 0;
String token;
List<OrderItem> orderitemlist = [];
Future<List<OrderItem>> _getMyOrders() async {
//Call for orderitemslist
return orderitemlist;
}
@override
void initState() {
super.initState();
_getMyOrders();
}
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xff757575),
child: Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
IconTextRowWidget(btnIcon: Icons.credit_card,btnText: 'Amount Due',btnSubText: '${totalAmount<10?10:totalAmount} QAR',),
Row(
children: <Widget>[
Expanded(
child: FlatButton(
color: Colors.green,
onPressed: (){
// Here I would like to close my current screen and reload orderslist, so that it will load all other pending joborders
_updateJobOrder();
Navigator.pop(context);
},
child: Text('Approve',style: TextStyle(color: Colors.white),),
),
),
Expanded(
child: FlatButton(
color: Colors.blueGrey,
onPressed: (){
// Here I would like to close my current screen and reload orderslist, so that it will load all other pending joborders
_updateJobOrder();
Navigator.pop(context);
},
child: Text('Reject',style: TextStyle(color: Colors.white),),
),
),
],
),
SizedBox(height: 10,)
// SizedBox(
// height: 30.0,
// ),
],
),
),
);
}
}
您可以声明一个 void 回调或函数作为第二屏幕的 属性 并从第一屏幕发送;这是一个例子;
class SecondScreen extends StatelessWidget {
final VoidCallback setStateOfFirstScreen;
const SecondScreen({Key key, this.setStateOfFirstScreen}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(icon: Icon(Icons.refresh), onPressed: setStateOfFirstScreen),
],
),
body: Center(),
);
}
}
class FistScreen extends StatefulWidget {
@override
_FistScreenState createState() => _FistScreenState();
}
class _FistScreenState extends State<FistScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: FlatButton(
child: Text("Go to the second screen"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (c) => SecondScreen(
setStateOfFirstScreen: () => setState(() {}),
),
),
);
},
),
),
);
}
}
当我检查你的代码时,我意识到你需要将函数发送给你的第一个小部件的孙子,
- 您需要在
OrdersListWidget
中声明一个函数,因为此小部件是访问第二个屏幕的唯一方式。
class OrdersListWidget extends StatelessWidget {
int Eid;
String Uid;
String Name;
String Contact;
String Status;
final VoidCallback setStateOfFirstScreen;
OrdersListWidget(
{@required this.Eid,
@required this.Uid,
@required this.Name,
@required this.Contact,
@required this.Status,
@required this.setStateOfFirstScreen});
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
ListTile(
leading: Text('#$Eid'),
title: Text(Name),
subtitle: Text(Contact),
trailing: Text(Status),
onTap: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: SecondScreen(OrderId: Eid, setStateOfFirstScreen: setStateOfFirstScreen),
),
),
);
},
),
Divider(),
],
);
}
}
- 并将 setState 作为第一个页面的参数发送到
OrdersListWidget
;
ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return OrdersListWidget(
Eid: snapshot.data[index].Eid,
Uid: snapshot.data[index].Uid.toString(),
Name: snapshot.data[index].Name.toString(),
Contact: snapshot.data[index].Contact.toString(),
Status: snapshot.data[index].OrderStat.toString(),
setStateOfFirstScreen: () => setState(() {}),
);
},
);
- 将
setStateOfFirstScreen
发送到 SecondScreen
并在那里使用它来设置第一个屏幕的状态;
class SecondScreen extends StatefulWidget {
final int OrderId;
final VoidCallback setStateOfFirstScreen;
SecondScreen({@required this.OrderId, @required this.setStateOfFirstScreen});
@override
_SecondScreenState createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
Future<http.Response> _updateJobOrder() async {
//Run Update code here
}
double totalAmount = 0;
String token;
List<OrderItem> orderitemlist = [];
Future<List<OrderItem>> _getMyOrders() async {
//Call for orderitemslist
return orderitemlist;
}
@override
void initState() {
super.initState();
_getMyOrders();
}
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xff757575),
child: Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
IconTextRowWidget(
btnIcon: Icons.credit_card,
btnText: 'Amount Due',
btnSubText: '${totalAmount < 10 ? 10 : totalAmount} QAR',
),
Row(
children: <Widget>[
Expanded(
child: FlatButton(
color: Colors.green,
onPressed: () {
// Here I would like to close my current screen and reload orderslist, so that it will load all other pending joborders
_updateJobOrder();
Navigator.pop(context);
widget.setStateOfFirstScreen();
},
child: Text(
'Approve',
style: TextStyle(color: Colors.white),
),
),
),
Expanded(
child: FlatButton(
color: Colors.blueGrey,
onPressed: () {
// Here I would like to close my current screen and reload orderslist, so that it will load all other pending joborders
_updateJobOrder();
Navigator.pop(context);
widget.setStateOfFirstScreen();
},
child: Text(
'Reject',
style: TextStyle(color: Colors.white),
),
),
),
],
),
SizedBox(
height: 10,
)
// SizedBox(
// height: 30.0,
// ),
],
),
),
);
}
}
我在 flutter 中有两个名为 'FirstScreen' 的屏幕,其中包含订单列表和 'SecondScreen' 用于某些操作。
我想在 'SecondScreen' 弹出时调用 'FirstScreen' 的设置状态,以便 'FirstScreen' 将重新加载挂单列表
SecondScreen 将接受或拒绝订单,FirstScreen 应从服务器重新加载数据,这是由 FirstScreen 中的方法 getOrders() 调用的。
首屏代码
import 'package:flutter/material.dart';
import 'package:nobleappshop/model/jobOrderItem.dart';
import 'package:nobleappshop/screens/SeconScreen.dart';
import 'package:nobleappshop/constants/constants.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class FirstScreen extends StatefulWidget {
@override
FirstScreenState createState() => FirstScreenState();
}
class FirstScreenState extends State<FirstScreen> {
Future<List<JobOrders>> _getPendingOrder() async {
var data = await http.get("$ApiServer/JobOrders/smOrdersPending");
var jsonData = json.decode(data.body);
List<JobOrders> joborderitemlist = [];
for (var i in jsonData) {
JobOrders jobOrders = JobOrders(
Eid: i["Eid"],
Uid: i["Uid"],
Name: i["Name"],
Contact: i["Contact"].toString(),
OrderStat: i["OrderStat"],
);
joborderitemlist.add(jobOrders);
}
return joborderitemlist;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('FirstScreen'),
),
body: FutureBuilder(
future: _getPendingOrder(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data.length <= 0) {
return Container(
child: Center(
child: Text('You have not made any orders yet...'),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return OrdersListWidget(
Eid: snapshot.data[index].Eid,
Uid: snapshot.data[index].Uid.toString(),
Name: snapshot.data[index].Name.toString(),
Contact: snapshot.data[index].Contact.toString(),
Status: snapshot.data[index].OrderStat.toString(),
);
},
);
}
} else {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
}
},
),
);
}
}
class OrdersListWidget extends StatelessWidget {
int Eid;
String Uid;
String Name;
String Contact;
String Status;
OrdersListWidget(
{@required this.Eid,
@required this.Uid,
@required this.Name,
@required this.Contact,
@required this.Status});
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
ListTile(
leading: Text('#$Eid'),
title: Text(Name),
subtitle: Text(Contact),
trailing: Text(Status),
onTap: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: SecondScreen(OrderId: Eid),
),
),
);
},
),
Divider(),
],
);
}
}
第二屏代码
import 'package:flutter/material.dart';
import 'package:nobleappshop/model/orderItem.dart';
import 'package:http/http.dart' as http;
import 'package:nobleappshop/widgets/iconTextWidget.dart';
import 'package:nobleappshop/widgets/scOrderItems.dart';
import 'package:nobleappshop/constants/constants.dart';
class SecondScreen extends StatefulWidget {
int OrderId;
SecondScreen({@required this.OrderId});
@override
_SecondScreenState createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
Future<http.Response> _updateJobOrder() async {
//Run Update code here
}
double totalAmount = 0;
String token;
List<OrderItem> orderitemlist = [];
Future<List<OrderItem>> _getMyOrders() async {
//Call for orderitemslist
return orderitemlist;
}
@override
void initState() {
super.initState();
_getMyOrders();
}
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xff757575),
child: Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
IconTextRowWidget(btnIcon: Icons.credit_card,btnText: 'Amount Due',btnSubText: '${totalAmount<10?10:totalAmount} QAR',),
Row(
children: <Widget>[
Expanded(
child: FlatButton(
color: Colors.green,
onPressed: (){
// Here I would like to close my current screen and reload orderslist, so that it will load all other pending joborders
_updateJobOrder();
Navigator.pop(context);
},
child: Text('Approve',style: TextStyle(color: Colors.white),),
),
),
Expanded(
child: FlatButton(
color: Colors.blueGrey,
onPressed: (){
// Here I would like to close my current screen and reload orderslist, so that it will load all other pending joborders
_updateJobOrder();
Navigator.pop(context);
},
child: Text('Reject',style: TextStyle(color: Colors.white),),
),
),
],
),
SizedBox(height: 10,)
// SizedBox(
// height: 30.0,
// ),
],
),
),
);
}
}
您可以声明一个 void 回调或函数作为第二屏幕的 属性 并从第一屏幕发送;这是一个例子;
class SecondScreen extends StatelessWidget {
final VoidCallback setStateOfFirstScreen;
const SecondScreen({Key key, this.setStateOfFirstScreen}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(icon: Icon(Icons.refresh), onPressed: setStateOfFirstScreen),
],
),
body: Center(),
);
}
}
class FistScreen extends StatefulWidget {
@override
_FistScreenState createState() => _FistScreenState();
}
class _FistScreenState extends State<FistScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: FlatButton(
child: Text("Go to the second screen"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (c) => SecondScreen(
setStateOfFirstScreen: () => setState(() {}),
),
),
);
},
),
),
);
}
}
当我检查你的代码时,我意识到你需要将函数发送给你的第一个小部件的孙子,
- 您需要在
OrdersListWidget
中声明一个函数,因为此小部件是访问第二个屏幕的唯一方式。
class OrdersListWidget extends StatelessWidget {
int Eid;
String Uid;
String Name;
String Contact;
String Status;
final VoidCallback setStateOfFirstScreen;
OrdersListWidget(
{@required this.Eid,
@required this.Uid,
@required this.Name,
@required this.Contact,
@required this.Status,
@required this.setStateOfFirstScreen});
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
ListTile(
leading: Text('#$Eid'),
title: Text(Name),
subtitle: Text(Contact),
trailing: Text(Status),
onTap: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: SecondScreen(OrderId: Eid, setStateOfFirstScreen: setStateOfFirstScreen),
),
),
);
},
),
Divider(),
],
);
}
}
- 并将 setState 作为第一个页面的参数发送到
OrdersListWidget
;
ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return OrdersListWidget(
Eid: snapshot.data[index].Eid,
Uid: snapshot.data[index].Uid.toString(),
Name: snapshot.data[index].Name.toString(),
Contact: snapshot.data[index].Contact.toString(),
Status: snapshot.data[index].OrderStat.toString(),
setStateOfFirstScreen: () => setState(() {}),
);
},
);
- 将
setStateOfFirstScreen
发送到SecondScreen
并在那里使用它来设置第一个屏幕的状态;
class SecondScreen extends StatefulWidget {
final int OrderId;
final VoidCallback setStateOfFirstScreen;
SecondScreen({@required this.OrderId, @required this.setStateOfFirstScreen});
@override
_SecondScreenState createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
Future<http.Response> _updateJobOrder() async {
//Run Update code here
}
double totalAmount = 0;
String token;
List<OrderItem> orderitemlist = [];
Future<List<OrderItem>> _getMyOrders() async {
//Call for orderitemslist
return orderitemlist;
}
@override
void initState() {
super.initState();
_getMyOrders();
}
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xff757575),
child: Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
IconTextRowWidget(
btnIcon: Icons.credit_card,
btnText: 'Amount Due',
btnSubText: '${totalAmount < 10 ? 10 : totalAmount} QAR',
),
Row(
children: <Widget>[
Expanded(
child: FlatButton(
color: Colors.green,
onPressed: () {
// Here I would like to close my current screen and reload orderslist, so that it will load all other pending joborders
_updateJobOrder();
Navigator.pop(context);
widget.setStateOfFirstScreen();
},
child: Text(
'Approve',
style: TextStyle(color: Colors.white),
),
),
),
Expanded(
child: FlatButton(
color: Colors.blueGrey,
onPressed: () {
// Here I would like to close my current screen and reload orderslist, so that it will load all other pending joborders
_updateJobOrder();
Navigator.pop(context);
widget.setStateOfFirstScreen();
},
child: Text(
'Reject',
style: TextStyle(color: Colors.white),
),
),
),
],
),
SizedBox(
height: 10,
)
// SizedBox(
// height: 30.0,
// ),
],
),
),
);
}
}