我在 flutter 朔迷离中有两个屏幕,分别是“FirstScreen”和订单列表,“SecondScreen”用于某些操作。
我想在“SecondScreen”弹出窗口上调用“FirstScreen”的setstate,以便“FirstScreen”将重新加载挂单flutter - 从Flutter中的SecondScreen调用FirstScreen的设置状态-LMLPHP的列表。
SecondScreen将接受或拒绝订单,并且FirstScreen应该从服务器重新加载数据,这由FirstScreen中的getOrders()方法调用。
flutter - 从Flutter中的SecondScreen调用FirstScreen的设置状态-LMLPHP
FirstScreen代码

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(),
      ],
    );
  }
}
SecondScreen代码
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,
//            ),
          ],
        ),
      ),
    );
  }
}

最佳答案

当我检查代码时,我意识到您需要将函数发送给第一个小部件的孙子,

  • 您需要在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 - 从Flutter中的SecondScreen调用FirstScreen的设置状态,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63982771/

    10-11 07:34