Flutter从凸起按钮的onPressed调用FutureBuilder不会调用builder属性

a34*_*254 1 dart flutter

我正在尝试学习Dart / Flutter,并且正在研究一个示例,该示例在应用程序上有一个显示“获取数据”的按钮,当我触摸它时,我想从一个宁静的服务中检索JSON数据。

我看到在fetchPost中调用了Web服务,但是未调用FutureBuilder的builder属性。

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Restul Test',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              onPressed: (){
                FutureBuilder<ResultsList>(
                  future: fetchPost(),
                  builder: (context, snapshot){
                    print('In Builder');
                  }
                );
              },
              child: Text('Get data'),
            )
          ],
        ),
      )
    );
  }
}

Future<ResultsList> fetchPost() async {
    final response =  await http.get('http://mywebserviceurl');

    if (response.statusCode == 200){
      print('Received data');
      return ResultsList.fromJson(json.decode(response.body));
    }
    else {
      throw Exception('Failed to load data');
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,有趣的是,如果我将FutureBuilder从按钮的onPressed移到Center的子级,我确实会看到builder属性被调用。

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Restul Test',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: FutureBuilder<ResultsList>(
                future: fetchPost(),
                builder: (context, snapshot){
                  print ('In Builder');
                  return Container();
                }
              )
      )
    );
  }
}

Future<ResultsList> fetchPost() async {
    final response =  await http.get('http://mywebserviceurl');

    if (response.statusCode == 200){
      print('Received data');
      return ResultsList.fromJson(json.decode(response.body));
    }
    else {
      throw Exception('Failed to load data');
    }
}
Run Code Online (Sandbox Code Playgroud)

显然我错过了一些东西,但是知道我在做什么错吗?

And*_*sky 10

如果您想从请求中获取一些数据,则不需要FutureBuilder。你可以做:

RaisedButton(
          onPressed: (){
            fetchPost().then((result) {
                print('In Builder');
            })
          },
          child: Text('Get data'),
        )
Run Code Online (Sandbox Code Playgroud)

要么

RaisedButton(
          onPressed: () async {
            var result = await fetchPost()
            print('In Builder');
          },
          child: Text('Get data'),
        )
Run Code Online (Sandbox Code Playgroud)

  • 如果您从异步请求中获取一些数据,然后您必须显示小部件 - 那么您需要 `FutureBuilder`。例如,您必须在某些小部件中显示 `fetchPost` 请求的结果 (2认同)

Leo*_* Nx 5

这里面的onPressed方法RaisedButton其实什么都没做。它只是创建一个新的FutureBuilder,除了现有的之外什么都不做^^ 就像你只是调用1+1;,它只是创建一个值,但该值不用于做任何事情。

RaisedButton(
  onPressed: (){
    FutureBuilder<ResultsList>(
      future: fetchPost(),
      builder: (context, snapshot){
        print('In Builder');
      }
    );
  },
  child: Text('Get data'),
)
Run Code Online (Sandbox Code Playgroud)

您可能已经body被分配到一个Widget(可以只是被称为body或任何您想要的^^),然后您可以在setState((){body = FutureBuilder(/*...*/});呼叫中更改它。