【问题标题】:update get query data every 20 sec in flutter在颤动中每 20 秒更新一次获取查询数据
【发布时间】:2021-11-24 15:33:01
【问题描述】:

我有一个页面,在这个页面上我展示了数据卡。我应要求收到此数据(getTaskDetails)。我得到一组数据并在卡片上显示这些数据。但问题是我想每 20 秒进行一次这些查询。更新我页面上的数据。这是我的代码:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import  'package:uhf_scan/model/setting/globalvar.dart' as global;
import 'dart:async';
import 'dart:io';
import 'dart:convert';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:uhf_scan/model/PageUhf/PageUhf.dart';
import 'package:qrscan/qrscan.dart' as scanner;
import 'package:flutter/services.dart';
 class TaskList extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: TaskListParse(),

    );
  }

}
class TaskListParse extends StatefulWidget {
  TaskListParse() : super();
  @override
  _JsonParseObjectsTask createState() => _JsonParseObjectsTask();
}

class _JsonParseObjectsTask extends State <StatefulWidget> {
  String limit = global.limit.toString();
  List<TaskDetails> _searchResult = [];
  List<TaskDetails> _taskDetails = [];
  List<TaskDetails> _taskBarcode = [];
  TextEditingController controller = new TextEditingController();

  String? _mySeals;
  
  Future<Null> getTaskDetails() async {

    final String url = global.urlVar ;

    HttpClient client = new HttpClient();

    client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
    
    final request = await client
        .getUrl(Uri.parse(url))
        .timeout(Duration(seconds: 5));

    HttpClientResponse response = await request.close();
    
    var responseBody = await response.transform(utf8.decoder).join();
    
    final responseJson = json.decode(responseBody);
    if (200 == response.statusCode) {
      setState(() {
        for (Map<String,dynamic> user in responseJson) {
          _taskDetails.add(TaskDetails.fromJson(user));
        }
      });
    }
  }

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

    getTaskDetails();
  }

  Widget _buildUsersList() {
    return new ListView.builder(
      itemCount: _taskDetails.length,
      itemBuilder: (context, index) {
        return new Card(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(15.0),
          ),
          color: Colors.white38,
          margin: EdgeInsets.symmetric(vertical: 7),
          child: ListTile(
              title: Text(
                _taskDetails[index].name,
                style: TextStyle(fontSize: 15,
                  color: Colors.black)
              ),
              leading: FaIcon(FontAwesomeIcons.truck),
              onTap: () =>
              {
                  global.taskId =  _taskDetails[index].id,
                  global.taskName =  _taskDetails[index].name,
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => ScanUhf()),
                )
              }
          ),
        );
      },
    );
  }

  Widget _buildSearchResults() {
    return new ListView.builder(
      itemCount: _searchResult.length,
      itemBuilder: (context, i) {
        return new Card(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(15.0),
          ),
          color: Colors.white38,
          margin: EdgeInsets.symmetric(vertical: 7),
          child: ListTile(
              title: Text(
                _searchResult[i].name,
                style: TextStyle(fontSize: 15),
              ),
              leading: Icon(
                Icons.home_outlined,
                size: 30,
                color: Colors.black87,
              ),
              onTap: () =>
              {
                global.taskId =  _searchResult[i].id,
                global.taskName =  _searchResult[i].name,
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => ScanUhf()),
                )
              }
          ),
        );
      },
    );
  }

  Widget _buildSearchBox() {

    return new Container(
      color: Colors.blueGrey,
      padding: const EdgeInsets.all(8.0),
      child: new Card(
        margin: EdgeInsets.symmetric(vertical: 7),
        child: new ListTile(
          leading: new Icon(Icons.search),
          title: new TextField(
            controller: controller,
            decoration: new InputDecoration(
                hintText: 'Пошук', border: InputBorder.none),
            onChanged: onSearchTextChanged,
          ),
          trailing: new IconButton(
            icon: new Icon(Icons.cancel),
            onPressed: () {
              controller.clear();
              onSearchTextChanged('');
            },
          ),
        ),
      ),
    );
  }

  Widget _buildBody() {

    return new Scaffold(
      body:Container(
        child:Column(
          children: <Widget>[
            new Container(
                color: Theme.of(context).primaryColor, child: _buildSearchBox()),
            new Expanded(
                child: _searchResult.length != 0 || controller.text.isNotEmpty
                    ? _buildSearchResults()
                    : _buildUsersList()),
          ],
        ),

      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _scanQR();
          });
        },
        child: const Icon(Icons.qr_code_scanner_sharp),
        backgroundColor: Colors.pink,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: _buildBody()
    );
  }

  onSearchTextChanged(String text) async {
    _searchResult.clear();
    if (text.isEmpty) {
      setState(() {});
      return;
    }

    _taskDetails.forEach((userDetail) {
      if (userDetail.name.toLowerCase().contains(text.toLowerCase()))
        _searchResult.add(userDetail);
    });

    setState(() {});
  }

  Future _scanQR () async {
    try {
     String? cameraScanResult = await scanner.scan();
      setState(() {
       _mySeals = cameraScanResult; // setting string result with cameraScanResult
      });
    } on PlatformException catch (e) {
      print(e);
    }
  }
}

class TaskDetails {

  final String  id, name;
  
  TaskDetails({required this.id,required this.name});

  factory TaskDetails.fromJson(Map<String, dynamic> json) {
    return new TaskDetails(
      id: json['id'],
      name: json['name']
    );
  }
}

一切正常。但是要更新数据,我需要再次访问该页面。我想通过留在页面上来更新这些数据。我将不胜感激)

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    在您的 initstate 方法中,您可以启动一个计时器,该计时器每 20 秒触发一次,并将您的回调函数调用为:

    Timer.periodic(Duration(seconds: 20),(_) => getTaskDetails())
    

    现在您的 getTastDetails() 函数将每 20 秒调用一次,并且数据将被更新。 并且不要忘记在 dispose 方法中取消计时器。 我已经修改了您的代码以按您的预期工作!

        import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import  'package:uhf_scan/model/setting/globalvar.dart' as global;
    import 'dart:async';
    import 'dart:io';
    import 'dart:convert';
    import 'package:font_awesome_flutter/font_awesome_flutter.dart';
    import 'package:uhf_scan/model/PageUhf/PageUhf.dart';
    import 'package:qrscan/qrscan.dart' as scanner;
    import 'package:flutter/services.dart';
    class TaskList extends StatelessWidget {
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: TaskListParse(),
    
        );
      }
    
    }
    class TaskListParse extends StatefulWidget {
      TaskListParse() : super();
      @override
      _JsonParseObjectsTask createState() => _JsonParseObjectsTask();
    }
    
    class _JsonParseObjectsTask extends State <StatefulWidget> {
      String limit = global.limit.toString();
      List<TaskDetails> _searchResult = [];
      List<TaskDetails> _taskDetails = [];
      List<TaskDetails> _taskBarcode = [];
      TextEditingController controller = new TextEditingController();
    
      String? _mySeals;
    
      Future<Null> getTaskDetails() async {
    
        final String url = global.urlVar ;
    
        HttpClient client = new HttpClient();
    
        client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
    
        final request = await client
            .getUrl(Uri.parse(url))
            .timeout(Duration(seconds: 5));
    
        HttpClientResponse response = await request.close();
    
        var responseBody = await response.transform(utf8.decoder).join();
    
        final responseJson = json.decode(responseBody);
        if (200 == response.statusCode) {
          _taskDetails.clear();
          setState(() {
            for (Map<String,dynamic> user in responseJson) {
              _taskDetails.add(TaskDetails.fromJson(user));
            }
          });
        }
      }
      late Timer _timer;
      @override
      void initState() {
        _timer = Timer.periodic(Duration(seconds: 20),(_) => getTaskDetails());
        super.initState();
      }
    
      @override
      void dispose(){
        _timer.cancel();
        super.dispose();
      }
    
      Widget _buildUsersList() {
        return new ListView.builder(
          itemCount: _taskDetails.length,
          itemBuilder: (context, index) {
            return new Card(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(15.0),
              ),
              color: Colors.white38,
              margin: EdgeInsets.symmetric(vertical: 7),
              child: ListTile(
                  title: Text(
                      _taskDetails[index].name,
                      style: TextStyle(fontSize: 15,
                          color: Colors.black)
                  ),
                  leading: FaIcon(FontAwesomeIcons.truck),
                  onTap: () =>
                  {
                    global.taskId =  _taskDetails[index].id,
                    global.taskName =  _taskDetails[index].name,
                    Navigator.push(
                      context,
                      MaterialPageRoute(builder: (context) => ScanUhf()),
                    )
                  }
              ),
            );
          },
        );
      }
    
      Widget _buildSearchResults() {
        return new ListView.builder(
          itemCount: _searchResult.length,
          itemBuilder: (context, i) {
            return new Card(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(15.0),
              ),
              color: Colors.white38,
              margin: EdgeInsets.symmetric(vertical: 7),
              child: ListTile(
                  title: Text(
                    _searchResult[i].name,
                    style: TextStyle(fontSize: 15),
                  ),
                  leading: Icon(
                    Icons.home_outlined,
                    size: 30,
                    color: Colors.black87,
                  ),
                  onTap: () =>
                  {
                    global.taskId =  _searchResult[i].id,
                    global.taskName =  _searchResult[i].name,
                    Navigator.push(
                      context,
                      MaterialPageRoute(builder: (context) => ScanUhf()),
                    )
                  }
              ),
            );
          },
        );
      }
    
      Widget _buildSearchBox() {
    
        return new Container(
          color: Colors.blueGrey,
          padding: const EdgeInsets.all(8.0),
          child: new Card(
            margin: EdgeInsets.symmetric(vertical: 7),
            child: new ListTile(
              leading: new Icon(Icons.search),
              title: new TextField(
                controller: controller,
                decoration: new InputDecoration(
                    hintText: 'Пошук', border: InputBorder.none),
                onChanged: onSearchTextChanged,
              ),
              trailing: new IconButton(
                icon: new Icon(Icons.cancel),
                onPressed: () {
                  controller.clear();
                  onSearchTextChanged('');
                },
              ),
            ),
          ),
        );
      }
    
      Widget _buildBody() {
    
        return new Scaffold(
          body:Container(
            child:Column(
              children: <Widget>[
                new Container(
                    color: Theme.of(context).primaryColor, child: _buildSearchBox()),
                new Expanded(
                    child: _searchResult.length != 0 || controller.text.isNotEmpty
                        ? _buildSearchResults()
                        : _buildUsersList()),
              ],
            ),
    
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              setState(() {
                _scanQR();
              });
            },
            child: const Icon(Icons.qr_code_scanner_sharp),
            backgroundColor: Colors.pink,
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
            body: _buildBody()
        );
      }
    
      onSearchTextChanged(String text) async {
        _searchResult.clear();
        if (text.isEmpty) {
          setState(() {});
          return;
        }
    
        _taskDetails.forEach((userDetail) {
          if (userDetail.name.toLowerCase().contains(text.toLowerCase()))
            _searchResult.add(userDetail);
        });
    
        setState(() {});
      }
    
      Future _scanQR () async {
        try {
          String? cameraScanResult = await scanner.scan();
          setState(() {
            _mySeals = cameraScanResult; // setting string result with cameraScanResult
          });
        } on PlatformException catch (e) {
          print(e);
        }
      }
    }
    
    class TaskDetails {
    
      final String  id, name;
    
      TaskDetails({required this.id,required this.name});
    
      factory TaskDetails.fromJson(Map<String, dynamic> json) {
        return new TaskDetails(
            id: json['id'],
            name: json['name']
        );
      }
    }
    

    【讨论】:

    • 感谢回答帮助),但问题是数据没有更新,而是添加了。也就是说,如果我有 3 张卡片(来自一个数组对象)。然后在 20 秒内,这些卡片将变为 6,然后是 9。你明白我在说什么吗?)
    • 好的,问题是每当调用 getTaskDetails() 时,它只是将新数据添加到列表中,即 _taskDetails。为了解决这个问题,我们可以在将新数据添加到列表之前使用 _taskDetails.clear() 从变量 _taskDetails 中删除所有先前的对象。我已经用这些提到的更改更新了我的答案中的代码。如果还有问题,请告诉我!
    猜你喜欢
    • 2011-04-23
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    相关资源
    最近更新 更多