加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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数据呈现小部件.
我在initState()上创建了这个小部件的实例,然后我进行了异步调用.

我发现一些文档说我们应该使用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(),);
    }
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读