如何从FutureBuilder或异步代码构建PreferredSizeWidget,而不是Widget?

时间:2019-10-29 16:20:22

标签: flutter flutter-layout

我知道如何从FutureBuilder构建窗口小部件,所以这是我的future / async函数,例如:

connection.json

如果我想构建一个AppBar Future<Null> myFuture() async { // etc. } ,就可以了:

title

现在,我想构建一个期望PreferredSizeWidget的AppBar的class MyStuff extends StatelessWidget { @override Widget build(BuildContext context) { return AppBar( title: FutureBuilder( future: myFuture(), builder: (context, snapshot) { // etc... return Text("blahblah"); } )); } } ,所以这可行,但是不异步:

bottom

但是我如何以将来/异步的方式使用它?这甚至无法编译:

class MyStuff2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return AppBar(
      bottom: PreferredSize(),
    );
  }
}

2 个答案:

答案 0 :(得分:0)

由于FutureBuilder返回了一个Widget,它将无法正常工作,因此,您可以做的是将无状态生成器转换为有状态生成器,然后创建自己的“ PreferredSizeFutureBuilder”

import 'package:flutter/material.dart';

class PreferredSizeFutureBuilder extends StatefulWidget {
  @override
  _PreferredSizeFutureBuilderState createState() =>
      _PreferredSizeFutureBuilderState();
}

class _PreferredSizeFutureBuilderState
    extends State<PreferredSizeFutureBuilder> {
  bool isCompleted = false;

  @override
  void initState() {
    super.initState();
    myFuture();
  }

  Future<void> myFuture() async {
    //do something

    setState(() {
      isCompleted = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return AppBar(
        bottom: isCompleted //we check if the future has ended
            ? PreferredSize(
                child: YourComponent(), //your component
                preferredSize: Size.fromHeight(12.0), //the size you want
              )
            : null); //if the future is loading we don't return anything, you can add your loading widget here
  }
}

当然,这意味着快照对象将无法工作,而是使用isCompleted bool来检查您的将来是否完成,甚至可以使用ConnectionState而不是布尔值来执行“快照”行为

答案 1 :(得分:0)

您可以将FutureBuilder包装到PreferredSize-Widget中。 无需创建自己的实现PreferredSize的FutureBuilder-Widget。

    class MyStuff2 extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return AppBar(
          bottom: PreferredSize(
             child: FutureBuilder(future: _getData(), builder: (BuildContext context, AsyncSnapshot snapshot) {
               if(snapshot.data != null) {
                 return Text(snapshot.data);
                } else {
                 return Text('Loading...');
                }
            ),
             preferredSize: Size.fromHeight(50.0),
        );
      }
    }