简体   繁体   English

如何在 flutter 的 build 方法中调用 provider 中的方法?

[英]how to call the method in provider inside the build method in flutter?

i have a method in the class which extends changeNotifier which gets the data from API.我在 class 中有一个方法,它扩展了从 API 获取数据的 changeNotifier。 now I want to call this method whenever page is opened in the build method but when I call that method it is repeatedly called because of the notifyListeners method.现在我想在构建方法中打开页面时调用此方法,但是当我调用该方法时,由于 notifyListeners 方法而重复调用它。 I want to know how to call method only once.我想知道如何只调用一次方法。

ReportProvider.dart ReportProvider.dart

class ReportProvider extends ChangeNotifier
{
  static DateFormat dateFormat = new DateFormat('dd-MM-yyyy');
  static DateFormat actualDateFormat = new DateFormat("yyyy-MM-dd");
  String _toDate = dateFormat.format(new DateTime.now());
  String _actualToDate = actualDateFormat.format(new DateTime.now());
  String _actualFromDate = actualDateFormat.format(new DateTime.now().subtract(new Duration(days: 7)));
  String _fromDate = dateFormat.format(new DateTime.now().subtract(new Duration(days: 7)));
  bool _progressStatuc = false;
  bool _chartVisible = true;
  bool _errorVisible = false;
  String _errorMessage;

  String get errorMessage => _errorMessage;
  bool get errorVisible => _errorVisible;
  bool get chartVisible => _chartVisible;
  bool get progressStatus => _progressStatuc;
  String get toDate => _toDate;
  String get fromDate => _fromDate;

  List<PieData> _data = new List();

  List<PieData> get data => _data;

  Future<void> getReportData() async
  {
    Map<String,dynamic> sessiondata = await new Utilities().getSessionData();
    int shopid = sessiondata['shopid'];
    Map<String,String> reportData = new Map();
    reportData['shopid'] = shopid.toString();
    reportData["fromdate"] = _actualFromDate;
    reportData["todate"] = _actualToDate;
    String token = await new Utilities().getToken();

    Map userHeader = {"token": token};
    print(reportData.toString());

    if(await new Utilities().checkInternet())
    {
      try
      {
        http.Response response = await http.post(EndPointUrl.report,body: reportData,headers: userHeader);
        String message = json.decode(response.body)['message'];
          List<ReportData> data = json.decode(response.body)['data'];
          data.forEach((reportData){
            _data.add(new PieData(reportData.menuname,reportData.itemcount));
          });
          notifyListeners();
      }
      catch(error)
      {
        _errorMessage = "Server error";
        notifyListeners();
      }

    }
    else
    {
      _progressStatuc = false;
      _chartVisible = false;
      _errorVisible = true;
      _errorMessage = "No Internet Connection";
      notifyListeners();
    }
  }




}

Report.dart报告.dart

class Report extends StatefulWidget
{
  @override
  State<StatefulWidget> createState() {
    return ReportState();
  }

}

class ReportState extends State<Report>
{
  @override
  Widget build(BuildContext context) {

    final reportProvider = Provider.of<ReportProvider>(context);

    reportProvider.getReportData();
    //yprint(reportProvider.data.toString());
    if(reportProvider.errorMessage != null &&  reportProvider.errorMessage.contains("Internet"))
    {
      showDialog(
        context: context,
        builder: (BuildContext context){
          return AlertDialog(
            title: Text("Error"),
            content: Text("${reportProvider.errorMessage}"),
            actions: <Widget>[
              FlatButton(
                child: Text("ok"),
                onPressed: (){
                  Navigator.pop(context);
                },
              )
            ],
          );
        });
    }
   return Stack(
     children: <Widget>[
       Column(
         crossAxisAlignment: CrossAxisAlignment.start,
         children: <Widget>[
           Container(
             margin: EdgeInsets.fromLTRB(8, MediaQuery.of(context).size.height*0.05,0, 0),
             child: Text(
               "Report",
               style: TextStyle(fontSize: 28,color: Colors.black),
             ),
           ),
           Row(
             children: <Widget>[
               Expanded(
                 flex: 3,

                  child: Container(
                    margin: EdgeInsets.fromLTRB(8, 8, 0, 0),
                    child: GestureDetector(
                     onTap: (){
                       reportProvider.selectDate(context, "fromdate");
                     },
                     child: Text(
                       "${reportProvider.fromDate}",
                       style: TextStyle(color: Colors.black,fontSize: 16),
                     ),
                 ),
                  ),
               ),
               Expanded(
                 flex: 1,
                  child: Text(
                   "To",
                   style: TextStyle(fontSize: 16,color: Colors.grey),
                 ),
               ),
               Expanded(
                 flex: 3,
                  child: GestureDetector(
                   onTap: (){
                     reportProvider.selectDate(context, "todate");
                   },
                   child: Text(
                     "${reportProvider.toDate}",
                     style: TextStyle(color: Colors.black,fontSize: 16),
                   ),
                 ),
               ),
               Expanded(
                 flex: 1,
                  child: GestureDetector(
                   onTap: (){},
                   child: Icon(
                     Icons.check,
                     color: Theme.of(context).accentColor,
                   ),
                 ),
               )

             ],
           ),
          //  Visibility(
          //    visible: reportProvider.chartVisible,
          //     child: charts.PieChart<PieData>(

          //    ),
          //  ),
           Expanded(
              child: Visibility(
               visible: reportProvider.errorVisible,
               child: Container(
                 alignment: Alignment.center,
                 child: Column(
                   crossAxisAlignment: CrossAxisAlignment.center,
                   mainAxisAlignment: MainAxisAlignment.center,
                   children: <Widget>[
                     SvgPicture.asset('assets/images/undraw_report.svg',width: MediaQuery.of(context).size.width,height: MediaQuery.of(context).size.height*0.40),
                                    Text(
                                      "No Reports are available",
                                      style: TextStyle(color: Colors.black,fontSize: 20),
                                    )
                   ],
                 ),
               ),
             ),
           )

         ],
       ),

     ],
   );
  }

}

As per the documentation , build() method is going to be called every time something changes.根据文档,每次发生变化时都会调用 build() 方法。 If you want calls to be triggered just once, you could use initState() method and add some helpers methods to update the UI.如果您希望只触发一次调用,您可以使用initState()方法并添加一些帮助方法来更新 UI。 An example can be found here: https://flutter.dev/docs/get-started/flutter-for/android-devs#what-is-the-equivalent-of-runonuithread-in-flutter可以在这里找到一个示例: https://flutter.dev/docs/get-started/flutter-for/android-devs#what-is-the-equivalent-of-runonuithread-in-flutter

Example for async loading from the previous link, special attention to loadData method:上一个链接的异步加载示例,特别注意loadData方法:

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() {
  runApp(SampleApp());
}

class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SampleAppPage(),
    );
  }
}

class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

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

class _SampleAppPageState extends State<SampleAppPage> {
  List widgets = [];

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

    loadData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample App"),
      ),
      body: ListView.builder(
        itemCount: widgets.length,
        itemBuilder: (BuildContext context, int position) {
          return getRow(position);
        },
      ),
    );
  }

  Widget getRow(int i) {
    return Padding(
      padding: EdgeInsets.all(10.0),
      child: Text("Row ${widgets[i]["title"]}"),
    );
  }

  Future<void> loadData() async {
    String dataURL = "https://jsonplaceholder.typicode.com/posts";
    http.Response response = await http.get(dataURL);
    setState(() {
      widgets = json.decode(response.body);
    });
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM