J'ai deux écrans en flutter nommés «FirstScreen» avec la liste des commandes et «SecondScreen» pour certaines actions.

Je voudrais appeler setstate de 'FirstScreen' sur 'SecondScreen' pop, afin que le 'FirstScreen' recharge la liste des commandes en attente FirstScreen

SecondScreen acceptera ou rejettera les commandes et FirstScreen devrait recharger les données du serveur, qui est appelé par la méthode getOrders () dans FirstScreen. SecondScreen

Code 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(),
      ],
    );
  }
}

Code 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,
//            ),
          ],
        ),
      ),
    );
  }
}
1
Sulfy 20 sept. 2020 à 22:18

2 réponses

Meilleure réponse

Quand j'ai vérifié votre code, j'ai réalisé que vous deviez envoyer une fonction au petit-enfant de votre premier widget,

  1. Vous devez déclarer une fonction dans votre OrdersListWidget car ce widget est le seul moyen d'accéder au deuxième écran.
    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(),
          ],
        );
      }
    }
  1. Et envoyez setState au OrdersListWidget comme paramètre dans votre première page;
    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(() {}),
        );
      },
    );
  1. Envoyez le setStateOfFirstScreen au SecondScreen et utilisez-le là pour définir l'état du premier écran;

    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,
    //            ),
              ],
            ),
          ),
        );
      }
    }

1
malibayram91 25 sept. 2020 à 15:31

Vous pouvez déclarer un rappel annulé ou une fonction comme propriété du deuxième écran et l'envoyer à partir du premier écran; Voici un exemple;

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(() {}),
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}
1
malibayram91 20 sept. 2020 à 21:36