按下按钮时更新FutureBuilder

时间:2020-01-02 12:15:23

标签: flutter

我要显示一个检索到的对象,该对象在按下按钮时调用__file__

当我按下api时,我想更新FutureBuilder小部件:

floatingActionButton
    class PostScreen extends StatefulWidget {
      const PostScreen();

      @override
      State<StatefulWidget> createState() => _PostScreenState();
    }

    class _PostScreenState extends State<PostScreen> {
    Future<Post> _post;
    PostApi _postApi;

    @override
      void initState() {
        super.initState();    
       _postApi = Provider.of<PostApi>(context, listen: false);
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          floatingActionButton: FloatingActionButton(onPressed: () {       
            setState((){
             _post = _postApi.fetchPost();          
          }); }), 
          appBar: AppBar(title: const Text('Post')),
          body:     
        FutureBuilder<Post>(
            future: _post,
            builder: (BuildContext context, AsyncSnapshot<Post> snapshot)   {
              return snapshot.connectionState == ConnectionState.done
                  ? snapshot.hasData
                      ? _buildRoot(snapshot.data)
                      :  Text(snapshot.error.toString());
                  : const Text('...');
            }),
            ) ;
      }
class Post {
  Post.fromJson(this.data);
  dynamic data;  
}

一切正常,但是在class PostApi{ PostApi(this._httpManager); final HttpManager _httpManager; Future<Post> fetchPost() async { final http.Response response = await _httpManager.get('https://jsonplaceholder.typicode.com/posts/1'); if (response.statusCode == 200) { return Post.fromJson(json.decode(response.body)); } else { throw Exception('Failed to load post'); } } 方法中有一个例外时,我遇到了问题。例如:

fetchPost

在这种情况下, Future<Post> fetchPost() async { final http.Response response = await _httpManager.get('https://jsonplaceholder.typicode.com/posts/1'); throw Exception('Failed to load post'); } } 连接状态处于正在等待状态,而不是完成

我做错了什么?

1 个答案:

答案 0 :(得分:1)

您的代码段语法错误,我无法重现
您的throw Exceptionswitch case配合正常
您可以在

下复制粘贴运行完整代码

代码段

builder: (BuildContext context, AsyncSnapshot<Post> snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                return Text('Input a URL to start');
              case ConnectionState.waiting:
                print("waiting");
                return Text('waiting');
              case ConnectionState.active:
                print("active");
                return Text('active');
              case ConnectionState.done:
                if (snapshot.hasError) {
                  print("has Error");
                  return Text(
                    '${snapshot.error}',
                    style: TextStyle(color: Colors.red),
                  );
                } else {
                  return Text(snapshot.data.data.toString());
                }
            }
          })

工作演示

enter image description here

enter image description here

完整代码

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

class Post {
  Post.fromJson(this.data);
  dynamic data;
}

class PostApi {
  PostApi();

  //final HttpManager _httpManager;

  Future<Post> fetchPost() async {
    final http.Response response =
        await http.get('https://jsonplaceholder.typicode.com/posts/1');

    throw Exception('Failed to load post');

    if (response.statusCode == 200) {
      return Post.fromJson(json.decode(response.body));
    } else {
      throw Exception('Failed to load post');
    }
  }
}

class PostScreen extends StatefulWidget {
  const PostScreen();

  @override
  State<StatefulWidget> createState() => _PostScreenState();
}

class _PostScreenState extends State<PostScreen> {
  Future<Post> _post;
  PostApi _postApi = PostApi();

  @override
  void initState() {
    super.initState();
    _post = _postApi.fetchPost();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(onPressed: () {
        setState(() {
          _post = _postApi.fetchPost();
        });
      }),
      appBar: AppBar(title: const Text('Post')),
      body: FutureBuilder<Post>(
          future: _post,
          builder: (BuildContext context, AsyncSnapshot<Post> snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                return Text('Input a URL to start');
              case ConnectionState.waiting:
                print("waiting");
                return Text('waiting');
              case ConnectionState.active:
                print("active");
                return Text('active');
              case ConnectionState.done:
                if (snapshot.hasError) {
                  print("has Error");
                  return Text(
                    '${snapshot.error}',
                    style: TextStyle(color: Colors.red),
                  );
                } else {
                  return Text(snapshot.data.data.toString());
                }
            }
          }),
    );
  }
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: PostScreen(),
    );
  }
}

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>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}