【问题标题】:Flutter run async operation on object creationFlutter 在对象创建时运行异步操作
【发布时间】:2019-06-30 15:57:54
【问题描述】:

我是 Flutter 的新手,我知道这是一个非常基本的问题,但我已经被这个问题困扰了三天。我只想从 API 中获取有关对象创建的数据。当您运行代码时,它会引发异常但是当您热重载它时,异步操作开始正常工作。请告诉我我错在哪里。我自己也做了额外的课程,尽管应该避免使用这种方法进行编码。

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

void main(){
    runApp(
       MaterialApp(
        title : "Quake",
        home :  HomePage()
      )
    );
}
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    super.initState();
    dataRepository.init();
  }
  @override
  Widget build(BuildContext context) {
    return Reading();
  }
}
class Reading extends StatefulWidget {
  @override
  _ReadingState createState() => _ReadingState();
}
class _ReadingState extends State<Reading> {
  Map _data = Map();
  List _features = List();
  @override
  void initState() {
    super.initState();
    _data = dataRepository.getReading();
    _features = _data['features'];
  }
  @override
  Widget build(BuildContext context) {
    return  Scaffold(
        appBar:  AppBar(
          title:  Text("Quake"),
          centerTitle: true,
          backgroundColor: Colors.black,
        ),
        body :  Center(
            child :  ListView.builder(
              itemCount: _features.length,
              padding: const EdgeInsets.all(14.5),
              itemBuilder: (BuildContext context, int position){
                var format =  DateFormat.yMMMd("en_US").add_jm();
                var _date = format.format( DateTime.fromMicrosecondsSinceEpoch(_features[position]['properties']['time']*1000, isUtc: true));
                return  Column(
                  children: <Widget>[
                    Divider(height : 5.5),
                    ListTile(
                      title:  Text("$_date",
                          style:  TextStyle(fontSize: 16.0)),
                      subtitle:  Text("${_features[position]['properties']['place']}",
                          style:  TextStyle(fontSize: 13.0)),
                      leading:  CircleAvatar(
                          backgroundColor : Colors.black,
                          child :  Text("${_features[position]['properties']['mag']}", style:  TextStyle( color: Colors.white))
                      ),
                      onTap: () => _windowOnTapping(context, _features[position]['properties']['title']),
            )],);},)));}}

Future _windowOnTapping(BuildContext context, String message){
  var alert =  AlertDialog(
    title:  Text("Quakes"),
    content:  Text(message),
    actions: <Widget>[
      FlatButton ( child:  Text("OK"), onPressed: (){ Navigator.pop(context);})
    ],
  );
  showDialog( context: context, builder: (context)=> alert);
}
final DataRepository dataRepository = DataRepository._private();
class DataRepository{
  DataRepository._private();
  Map _data;
  void init() async{
    String apiUrl = 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson';
    http.Response response = await http.get(apiUrl);
    _data = json.decode(response.body);
  }
  Map getReading(){
    return _data;
  }
}

【问题讨论】:

  • 使用futurebuilder
  • 我认为你的 dataRepository.init() 只是创建了 Future。将来会执行。在调用 dataRepository.getReading() 之前,您的 dataRepository 未初始化。在 init() 内部初始化 dataRepository.streamOfData 并将其提供给 FutureBuilder。当您运行热重载时,dataRepository 已经初始化。或者你可以做 dataRepository.init().then(showMyDataInAWidget());
  • 哇!一周内有两个地震应用程序。 stackoverflow.com/questions/54526977/…

标签: api asynchronous dart flutter


【解决方案1】:

使用 FutureBuilder 读取 Future 并仅在组件返回后渲染组件,如下所示:

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

void main() {
  runApp(MaterialApp(title: "Quake", home: HomePage()));
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

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

  @override
  Widget build(BuildContext context) {
    return Reading();
  }
}

class Reading extends StatefulWidget {
  @override
  _ReadingState createState() => _ReadingState();
}

class _ReadingState extends State<Reading> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Quake"),
          centerTitle: true,
          backgroundColor: Colors.black,
        ),
        body: FutureBuilder<Map>(
            future: dataRepository.getReading(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                var features = snapshot.data['features'];
                return Center(
                    child: ListView.builder(
                  itemCount: features.length,
                  padding: const EdgeInsets.all(14.5),
                  itemBuilder: (BuildContext context, int position) {
                    var format = DateFormat.yMMMd("en_US").add_jm();
                    var _date = format.format(
                        DateTime.fromMicrosecondsSinceEpoch(
                            features[position]['properties']['time'] * 1000,
                            isUtc: true));
                    return Column(
                      children: <Widget>[
                        Divider(height: 5.5),
                        ListTile(
                          title:
                              Text("$_date", style: TextStyle(fontSize: 16.0)),
                          subtitle: Text(
                              "${features[position]['properties']['place']}",
                              style: TextStyle(fontSize: 13.0)),
                          leading: CircleAvatar(
                              backgroundColor: Colors.black,
                              child: Text(
                                  "${features[position]['properties']['mag']}",
                                  style: TextStyle(color: Colors.white))),
                          onTap: () => _windowOnTapping(context,
                              features[position]['properties']['title']),
                        )
                      ],
                    );
                  },
                ));
              } else {
                return Text("Loading");
              }
            }));
  }
}

Future _windowOnTapping(BuildContext context, String message) {
  var alert = AlertDialog(
    title: Text("Quakes"),
    content: Text(message),
    actions: <Widget>[
      FlatButton(
          child: Text("OK"),
          onPressed: () {
            Navigator.pop(context);
          })
    ],
  );
  showDialog(context: context, builder: (context) => alert);
}

final DataRepository dataRepository = DataRepository._private();

class DataRepository {
  DataRepository._private();

  Future<Map> getReading() async {
    String apiUrl =
        'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson';
    http.Response response = await http.get(apiUrl);
    var data = json.decode(response.body);
    print(data);
    return data;
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    • 2018-06-04
    • 2016-09-27
    • 2015-08-02
    相关资源
    最近更新 更多