async-await – 异步调用后的Flutter,渲染小部件
发布时间:2020-12-14 14:49:38 所属栏目:百科 来源:网络整理
导读:我想渲染一个需要HTTP调用的小部件来收集一些数据. 得到以下代码(简化) import 'package:flutter/material.dart';import 'dart:async';import 'dart:convert';void main() { runApp(new MyApp());}class MyApp extends StatelessWidget { // This widget is
我想渲染一个需要HTTP调用的小部件来收集一些数据.
得到以下代码(简化) import 'package:flutter/material.dart'; import 'dart:async'; import 'dart:convert'; void main() { runApp(new MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter demo',theme: new ThemeData( primarySwatch: Colors.blue,),home: new MyHomePage(title: 'async demo'),); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key,this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => new _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { var asyncWidget; @override initState() { super.initState(); loadData().then((result) { print(result); setState(() { asyncWidget = result; }); }); } loadData() async { var widget = new AsyncWidget(); return widget.build(); } @override Widget build(BuildContext context) { if(asyncWidget == null) { return new Scaffold( appBar: new AppBar( title: new Text("Loading..."),); } else { return new Scaffold( appBar: new AppBar( title: new Text(widget.title),body: new Center( child: this.asyncWidget,); } } } class MyRenderer { MyRenderer(); Widget render (List data) { List<Widget> renderedWidgets = new List<Widget>(); data.forEach((element) { renderedWidgets.add(new ListTile( title: new Text("one element"),subtitle: new Text(element.toString()),)); }); var lv = new ListView( children: renderedWidgets,); return lv; } } class MyCollector { Future gather() async { var response = await // do the http request here; return response.body; } } class AsyncWidget { MyCollector collector; MyRenderer renderer; AsyncWidget() { this.collector = new MyCollector(); this.renderer = new MyRenderer(); } Widget build() { var data = this.collector.gather(); data.then((response) { var responSEObject = JSON.decode(response); print(response); return this.renderer.render(responSEObject); }); data.catchError((error) { return new Text("Oups"); }); } } 我的代码是这样的:使用异步数据的小部件采用收集器(进行http调用)和渲染器,它将使用http数据呈现小部件. 我发现一些文档说我们应该使用setState()方法用新数据更新小部件,但这对我不起作用. 但是,当我放置一些日志时,我看到HTTP调用已完成,并且调用了setState()方法,但窗口小部件不会更新. 解决方法
最好的方法是使用
FutureBuilder.
从FutureBuilder文档: new FutureBuilder<String>( future: _calculation,// a Future<String> or null builder: (BuildContext context,AsyncSnapshot<String> snapshot) { switch (snapshot.connectionState) { case ConnectionState.none: return new Text('Press button to start'); case ConnectionState.waiting: return new Text('Awaiting result...'); default: if (snapshot.hasError) return new Text('Error: ${snapshot.error}'); else return new Text('Result: ${snapshot.data}'); } },) 另一件事是你在State.build方法之外构建你的小部件并保存小部件本身,这是一种反模式.实际上,您应该每次在构建方法中构建窗口小部件. 你可以在没有FutureBuilder的情况下使用它,但你应该保存http调用的结果(适当处理),然后使用你的构建函数中的数据. 看到这一点,但请注意,使用FutureBuilder是一种更好的方法,我只是提供这个来供你学习. import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; void main() { runApp(new MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter demo',this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => new _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { List data; @override initState() { super.initState(); new Future<String>.delayed(new Duration(seconds: 5),() => '["123","456","789"]').then((String value) { setState(() { data = json.decode(value); }); }); } @override Widget build(BuildContext context) { if (data == null) { return new Scaffold( appBar: new AppBar( title: new Text("Loading..."),body: new Center( child: new ListView( children: data .map((data) => new ListTile( title: new Text("one element"),subtitle: new Text(data),)) .toList(),); } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |