how to refresh state on Navigator.Pop or Push in flutter

雨燕双飞 提交于 2020-01-16 05:24:05

问题


Here I have two pages first is called BSP_signup_terms page and the second is Bsp_Service_page. when I am on BSP_signup_terms on that page I have to select some checkbox based on the selected checkbox it will show me some data. but problem is that it will show me the complete data but when I get back to the BSP_signup_terms from Bsp_signup_page and I am changing the checkbox and then again when I am pressing next button it will not change the result it same as the previous result.

Here is the Image of Output Page

In this image I've attached both screen output when I am selecting only one checkbox it will render some value in service page and when I am back to the Terms and Condition page and select one more checkbox then it will not updating service page

Here is the code I've tried.


BSP_Signup_Terms_Page

class BspLicensedSignupTermsPage extends StatefulWidget {
  static const String routeName = "/bspLicensedSignupTerms";
  final BspSignupCommonModel bspSignupCommonModel;

  BspLicensedSignupTermsPage({
    Key key,
    @required this.bspSignupCommonModel,
  }) : super(key: key);

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

class _BspLicensedSignupTermsPageState
    extends State<BspLicensedSignupTermsPage> {
  @override
  void initState() {
    super.initState();
  }

  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  bool _isWalkIn = false;
  bool _isHome = false;
  bool _isOnDemand = false;



  Widget _buildselectcheckbox() {
    return Text(
      AppConstantsValue.appConst['bsplicensedsignupterms']['selectcheck']
          ['translation'],
    );
  }

  // Walkin
  _onCustomerWalkin(value) {
    setState(() {
      _isWalkIn = value;
    });
  }

  Widget _buildCustomerWalkIn() {
    return TudoConditionWidget(
      text: AppConstantsValue.appConst['bsplicensedsignupterms']
          ['CustomerWalkIn']['translation'],
      onChanged: (value) {
        print(value);
        _onCustomerWalkin(value);
      },
      validate: false,
    );
  }


  // Home
  _onCustomerInHome(value) {
    setState(() {
      _isHome = value;
    });
  }

  Widget _buildCustomerInHome() {
    return TudoConditionWidget(
      text: AppConstantsValue.appConst['bsplicensedsignupterms']
          ['CustomerInHome']['translation'],
      onChanged: (value) {
        _onCustomerInHome(value);
      },
      validate: false,
    );
  }

  Widget _buildCustomerInHomeHelp() {
    return Text(
      AppConstantsValue.appConst['bsplicensedsignupterms']['businesscheckhelp']
          ['translation'],
    );
  }

  // On Demand

  _onCustomerOnDemand(value) {
    setState(() {
      _isOnDemand = value;
    });
  }

  Widget _buildBusinessOnDemand() {
    return TudoConditionWidget(
      text: AppConstantsValue.appConst['bsplicensedsignupterms']
          ['BusinessOnDemand']['translation'],
      onChanged: (value) {
        _onCustomerOnDemand(value);
      },
      validate: false,
    );
  }

  Widget _buildBusinessOnDemandHelp() {
    return Text(AppConstantsValue.appConst['bsplicensedsignupterms']
        ['businessprovidehelp']['translation']);
  }

  @override
  Widget build(BuildContext context) {
    final appBar = AppBar(
      title: Text("Bsp Licensed Signup Terms and Condition"),
      leading: IconButton(
        icon: Icon(Icons.arrow_back_ios),
        onPressed: () {
          NavigationHelper.navigatetoBack(context);
        },
      ),
      centerTitle: true,
    );

    final bottomNavigationBar = Container(
      height: 56,
      //margin: EdgeInsets.symmetric(vertical: 24, horizontal: 12),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          new FlatButton.icon(
            icon: Icon(Icons.close),
            label: Text('Clear'),
            color: Colors.redAccent,
            textColor: Colors.black,
            padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(7),
            ),
            onPressed: () {
              _formKey.currentState.reset();
            },
          ),
          new FlatButton.icon(
            icon: Icon(FontAwesomeIcons.arrowCircleRight),
            label: Text('Next'),
            color: colorStyles["primary"],
            textColor: Colors.white,
            padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(7),
            ),
            onPressed: () {
              if (_formKey.currentState.validate()) {
                if (_isHome == false &&
                    _isOnDemand == false &&
                    _isWalkIn == false) {
                  showDialog(
                      barrierDismissible: false,
                      context: context,
                      builder: (context) => ShowErrorDialog(
                            title: Text('Select Service'),
                            content: Text(
                              'Please select atleast one service type to proceed next',
                            ),
                          ));
                } else {
                  BspSignupCommonModel model = widget.bspSignupCommonModel;
                  model.isWalkin = _isWalkIn;
                  model.isHome = _isHome;
                  model.isOnDemand = _isOnDemand;
                  print(model.toJson());
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) =>
                          BspServicePage(bspSignupCommonModel: model),
                    ),
                  );
                }
              }
            },
          ),
        ],
      ),
    );
    return new Scaffold(
      appBar: appBar,
      bottomNavigationBar: bottomNavigationBar,
      body: Container(
        height: double.infinity,
        width: double.infinity,
        child: Stack(
          children: <Widget>[

            SingleChildScrollView(
              child: SafeArea(

                child: Form(
                  autovalidate: true,
                  key: _formKey,
                  child: Scrollbar(
                    child: SingleChildScrollView(
                      dragStartBehavior: DragStartBehavior.down,
                      padding: const EdgeInsets.symmetric(horizontal: 10.0),
                      child: new Container(
                        decoration: BoxDecoration(
                            borderRadius: new BorderRadius.circular(25)),
                        child: new Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            _buildselectcheckbox(),
                            _buildCustomerWalkIn(),
                            _buildCustomerInHome(),
                            _buildCustomerInHomeHelp(),
                            _buildBusinessOnDemand(),
                            _buildBusinessOnDemandHelp(),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

BSP_Service_Page

class BspServicePage extends StatefulWidget {
  static const String routeName = "/bspService";
  final BspSignupCommonModel bspSignupCommonModel;

  BspServicePage({
    Key key,
    @required this.bspSignupCommonModel,
  }) : super(key: key);

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

class _BspServicePageState extends State<BspServicePage> {
  List<int> servicesIds = [];
  Map<String, bool> selection = {};
  List<BspServices.Service> selectedServices = [];
  SearchBarController _controller = new SearchBarController();
  String _searchText = '';
  bool refreshservices = true;

  @override
  void initState() {
    super.initState();
  }

  void _showErrorDialog(String message) {
    showDialog(
      barrierDismissible: false,
      context: context,
      builder: (context) => ShowErrorDialog(
        title: Text('An Error Occurred!'),
        content: Text(message),
      ),
    );
  }

  void refresh() {
    setState(() {
      refreshservices = !refreshservices;
    });
  }

  @override
  Widget build(BuildContext context) {
    var _bspServiceBloc = new BspServiceBloc();
    final appBar = SearchBar(
      controller: _controller,
      onQueryChanged: (String query) {
        print('Search Query $query');
        setState(() {
          _searchText = query;
        });
      },
      defaultBar: AppBar(
        centerTitle: true,
        leading: IconButton(
            icon: Icon(Icons.arrow_back_ios),
            onPressed: () {
              refresh();
              NavigationHelper.navigatetoBack(context);
            }),
        title: Text('Select Services'),
      ),
    );

    final bottomNavigationBar = Container(
      height: 56,
      // margin: EdgeInsets.symmetric(vertical: 24, horizontal: 12),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          new FlatButton.icon(
            icon: Icon(Icons.close),
            label: Text('Clear'),
            color: Colors.redAccent,
            textColor: Colors.black,
            padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(7),
            ),
            onPressed: () {
              print('reseting the state');
              setState(() {
                selection = {};
                servicesIds = [];
              });
            },
          ),
          new FlatButton.icon(
            icon: Icon(FontAwesomeIcons.arrowCircleRight),
            label: Text('Next'),
            color: colorStyles["primary"],
            textColor: Colors.white,
            padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(7),
            ),
            onPressed: () {
              BspSignupCommonModel model = widget.bspSignupCommonModel;
              model.servicesIds = servicesIds;
              model.services = selectedServices;
              print('servicesIds at the next button');
              print(servicesIds);
              print(model.toJson());
              if (servicesIds.length == 0) {
                _showErrorDialog(
                    'You need to select at least one service to proceed next!');
              } else {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => BusinessProfilePage(
                      bspSignupCommonModel: model,
                    ),
                  ),
                );
              }
            },
          ),
        ],
      ),
    );
    return new Scaffold(
      appBar: appBar,
      bottomNavigationBar: bottomNavigationBar,
      body: new BspServiceScreen(
        bspServiceBloc: _bspServiceBloc,
        bspSignupCommonModel: widget.bspSignupCommonModel,
        servicesIds: servicesIds,
        selection: selection,
        searchQuery: _searchText,
        selectedServices: selectedServices,
        refresh: refresh,
      ),
    );
  }
}

Bsp_service_screen

class BspServiceScreen extends StatefulWidget {
  final BspServiceBloc _bspServiceBloc;
  final String searchQuery;
  final List<int> servicesIds;
  final Map<String, bool> selection;
  final BspSignupCommonModel bspSignupCommonModel;
  final List<BspServices.Service> selectedServices;
  final Function refresh;

  const BspServiceScreen({
    Key key,
    @required BspServiceBloc bspServiceBloc,
    @required this.bspSignupCommonModel,
    @required this.servicesIds,
    @required this.selection,
    @required this.selectedServices,
    @required this.refresh,
    this.searchQuery,
  })  : _bspServiceBloc = bspServiceBloc,
        super(key: key);

  @override
  BspServiceScreenState createState() {
    return new BspServiceScreenState(_bspServiceBloc);
  }
}

class BspServiceScreenState extends State<BspServiceScreen> {
  final BspServiceBloc _bspServiceBloc;

  BspServiceScreenState(this._bspServiceBloc);
  // Map<String, bool> _selection = {};

  @override
  void initState() {
    super.initState();
    bool isHome = widget.bspSignupCommonModel.isHome;
    bool isWalkIn = widget.bspSignupCommonModel.isWalkin;
    bool isOnDemand = widget.bspSignupCommonModel.isOnDemand;
    this._bspServiceBloc.dispatch(LoadBspServiceEvent(
          countryId: 1,
          isHome: isHome,
          isOnDemand: isOnDemand,
          isWalkin: isWalkIn,
        ));
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<BspServiceBloc, BspServiceState>(
      bloc: widget._bspServiceBloc,
      builder: (
        BuildContext context,
        BspServiceState currentState,
      ) {
        if (currentState is UnBspServiceState) {
          return Center(child: CircularProgressIndicator());
        }
        if (currentState is ErrorBspServiceState) {
          return new Container(
            child: new Center(
              child: new Text(currentState.errorMessage ?? 'Error'),
            ),
          );
        }
        if (currentState is InBspServiceState) {
          // print(
          //     'in bsp service state, ${currentState.bspServices.servicesByCountry.length}');
          if (currentState.bspServices.servicesByCountry.length == 0) {
            return Container(
              child: Center(
                child: Text("No Services available for this combination"),
              ),
            );
          } else {
            return new Container(
              child:
                  _renderServices(currentState.bspServices.servicesByCountry),
            );
          }
        }
        return Container();
      },
    );
  }

  List<ServicesByCountry> finalList = new List();

  ListView _renderServices(List<ServicesByCountry> lovCountryServices) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (widget.searchQuery != '') {
        finalList.clear();
        lovCountryServices.forEach((ServicesByCountry data) {
          if (data.name
              .toLowerCase()
              .contains(widget.searchQuery.toLowerCase())) {
            setState(() {
              finalList.add(data);
            });
          } else {
            data.services.forEach((ServiceList.Service services) {
              if (services.name
                  .toLowerCase()
                  .contains(widget.searchQuery.toLowerCase())) {
                setState(() {
                  finalList.add(data);
                });
              }
            });
          }
        });
      } else {
        setState(() {
          finalList.clear();
          finalList.addAll(lovCountryServices);
        });
      }
    });
    return ListView.builder(
      shrinkWrap: true,
      padding: const EdgeInsets.all(8.0),
      itemCount: finalList.length,
      itemBuilder: (BuildContext context, int index) {
        ServicesByCountry item = finalList[index];
        List itemsList = item.services;
        return ExpansionTile(
          title: Text(item.name),
          children: List.generate(itemsList.length, (i) {
            widget.selection[itemsList[i].name] =
                widget.selection[itemsList[i].name] ?? itemsList[i].isSelected;
            return CheckboxListTile(
              title: Text(itemsList[i].name),
              value: widget.selection[itemsList[i].name],
              onChanged: (val) {
                setState(() {
                  widget.selection[itemsList[i].name] = val;
                  if (val) {
                    widget.servicesIds.add(itemsList[i].id);

                    List<BspServices.Service> services =
                        widget.selectedServices.where((service) {
                      return service.mainCategory == item.name;
                    }).toList();

                    SubCategory subService = new SubCategory(
                      id: itemsList[i].id,
                      name: itemsList[i].name,
                    );

                    List<SubCategory> subCategories = [];
                    if (services.length == 0) {
                      subCategories.add(subService);
                      widget.selectedServices.add(
                        new BspServices.Service(
                          mainCategory: item.name,
                          mainCategoryId: item.id,
                          subCategory: subCategories,
                        ),
                      );
                    } else {
                      print('services in else');
                      print(services[0].subCategory);
                      subCategories = services[0].subCategory;
                      subCategories.add(subService);
                    }
                  } else {
                    widget.servicesIds.removeWhere((service) {
                      return service == itemsList[i].id;
                    });

                    List<BspServices.Service> services =
                        widget.selectedServices.where((service) {
                      return service.mainCategory == item.name;
                    }).toList();

                    services[0].subCategory.removeWhere((subService) {
                      return subService.id == itemsList[i].id;
                    });
                  }
                });
                print('widget.servicesIds after set state');
                print(widget.servicesIds);
              },
            );
          }),
        );
      },
    );
  }
}

回答1:


You can use setState() after return to the first page:

Navigator.push(context, MaterialPageRoute(builder: (context) => Page2())).then((value) {
  setState(() {
    // refresh state
  });
});



回答2:


Please try below code:-

First you add one method async method:-

void redirectToNextScreen() async {
    final Route route = MaterialPageRoute(
        builder: (context) => BspServicePage(bspSignupCommonModel: model));
    final result = await Navigator.push(mContext, route);
    try {
      if (result != null) {
        if (result) {
          //Return callback here.
        }
      }
    } catch (e) {
      print(e.toString());
    }
  }

Then Next you can call this method in "BSP_Signup_Terms_Page" on Next button Pressed event.

Second you can add below line in "BspServicePage" screen Next and Cancel Events.

Navigator.pop(mContext, true); //true means refresh back page and false means not refresh.


来源:https://stackoverflow.com/questions/58388309/how-to-refresh-state-on-navigator-pop-or-push-in-flutter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!