Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dart 我应该什么时候使用FutureBuilder?_Dart_Flutter_Future_Builder - Fatal编程技术网

Dart 我应该什么时候使用FutureBuilder?

Dart 我应该什么时候使用FutureBuilder?,dart,flutter,future,builder,Dart,Flutter,Future,Builder,我想知道什么时候应该使用future builder。例如,如果我想发出http请求并在列表视图中显示结果,那么在您打开视图后,我应该使用future builder还是只构建一个ListViewBuilder,如: new ListView.builder( itemCount: _features.length, itemBuilder: (BuildContext context, int position) { ...stuff here... } 此外

我想知道什么时候应该使用future builder。例如,如果我想发出http请求并在列表视图中显示结果,那么在您打开视图后,我应该使用future builder还是只构建一个
ListViewBuilder
,如:

new ListView.builder(
        itemCount: _features.length,
        itemBuilder: (BuildContext context, int position) {
...stuff here...
}
此外,如果我不想构建一个列表视图,而是构建一些更复杂的东西,比如圆形图表,那么我应该使用future builder吗


希望足够清楚

FutureBuilder
删除样板代码

假设您希望在页面启动时从后端获取一些数据,并在数据到来之前显示加载程序

ListBuilder的任务:

FutureBuilder<String>(
    future: _fetchNetworkCall, // async work
    builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
       switch (snapshot.connectionState) {
         case ConnectionState.waiting: return Text('Loading....');
         default:
           if (snapshot.hasError)
              return Text('Error: ${snapshot.error}');
           else
          return Text('Result: ${snapshot.data}');
        }
      },
    )
widget.future.then<void>((T data) {
    if (_activeCallbackIdentity == callbackIdentity) {
      setState(() {
        _snapshot = AsyncSnapshot<T>.withData(ConnectionState.done, data);
      });
    }
}, onError: (Object error) {
  if (_activeCallbackIdentity == callbackIdentity) {
    setState(() {
      _snapshot = AsyncSnapshot<T>.withError(ConnectionState.done, error);
    });
  }
});
  • 有两个状态变量,
    datafrombend
    isLoadingFlag
  • 启动时,设置
    isLoadingFlag=true
    ,并在此基础上显示
    loader
  • 数据到达后,使用从后端获得的数据设置数据,并设置
    isLoadingFlag=false
    (显然是在
    setState
    内部)
  • 我们需要在小部件创建中使用
    if-else
    。如果
    isLoadingFlag
    true
    ,则显示
    加载程序
    ,否则显示
    数据
    。失败时,显示错误消息
FutureBuilder的任务:

FutureBuilder<String>(
    future: _fetchNetworkCall, // async work
    builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
       switch (snapshot.connectionState) {
         case ConnectionState.waiting: return Text('Loading....');
         default:
           if (snapshot.hasError)
              return Text('Error: ${snapshot.error}');
           else
          return Text('Result: ${snapshot.data}');
        }
      },
    )
widget.future.then<void>((T data) {
    if (_activeCallbackIdentity == callbackIdentity) {
      setState(() {
        _snapshot = AsyncSnapshot<T>.withData(ConnectionState.done, data);
      });
    }
}, onError: (Object error) {
  if (_activeCallbackIdentity == callbackIdentity) {
    setState(() {
      _snapshot = AsyncSnapshot<T>.withError(ConnectionState.done, error);
    });
  }
});
  • 在future Builder的
    future
    中指定异步任务
  • 基于
    连接状态
    ,显示消息(
    加载
    活动(流)
    完成
  • 基于
    数据(snapshot.hasrerror)
    ,显示视图
FutureBuilder的优点

  • 不使用两个状态变量和
    setState
  • 反应式编程(
    FutureBuilder
    将负责在数据到达时更新视图)
示例:

FutureBuilder<String>(
    future: _fetchNetworkCall, // async work
    builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
       switch (snapshot.connectionState) {
         case ConnectionState.waiting: return Text('Loading....');
         default:
           if (snapshot.hasError)
              return Text('Error: ${snapshot.error}');
           else
          return Text('Result: ${snapshot.data}');
        }
      },
    )
widget.future.then<void>((T data) {
    if (_activeCallbackIdentity == callbackIdentity) {
      setState(() {
        _snapshot = AsyncSnapshot<T>.withData(ConnectionState.done, data);
      });
    }
}, onError: (Object error) {
  if (_activeCallbackIdentity == callbackIdentity) {
    setState(() {
      _snapshot = AsyncSnapshot<T>.withError(ConnectionState.done, error);
    });
  }
});

因此,
FutureBuilder
是我们通常所做的包装器/样板文件,因此不应该对性能产生任何影响FutureBuilder示例

  • 当您想在异步调用后创建rander小部件时,请使用
    FutureBuilder()

    class _DemoState extends State<Demo> {
    
    @override
    Widget build(BuildContext context) {
      return FutureBuilder<String>(
        future: downloadData(), // function where you call your api
        builder: (BuildContext context, AsyncSnapshot<String> snapshot) {  // AsyncSnapshot<Your object type>
          if( snapshot.connectionState == ConnectionState.waiting){
              return  Center(child: Text('Please wait its loading...'));
          }else{
              if (snapshot.hasError)
                return Center(child: Text('Error: ${snapshot.error}'));
              else
                return Center(child: new Text('${snapshot.data}'));  // snapshot.data  :- get your object which is pass from your downloadData() function
          }
        },
      );
    }
    Future<String> downloadData()async{
      //   var response =  await http.get('https://getProjectList');    
      return Future.value("Data download successfully"); // return your response
    }
    }
    
    class\u DemoState扩展状态{
    @凌驾
    小部件构建(构建上下文){
    回归未来建设者(
    future:downloadData(),//调用api的函数
    生成器:(BuildContext上下文,异步快照){//AsyncSnapshot
    if(snapshot.connectionState==connectionState.waiting){
    返回中心(子项:Text('请等待其加载…');
    }否则{
    if(snapshot.hasError)
    返回中心(子项:Text('Error:${snapshot.Error}');
    其他的
    返回中心(子:新文本(“${snapshot.data}”);//snapshot.data:-获取从downloadData()函数传递的对象
    }
    },
    );
    }
    未来下载数据()异步{
    //var response=wait http.get('https://getProjectList');    
    return Future.value(“数据下载成功”);//返回您的响应
    }
    }
    
在future builder中,它调用future函数来等待结果,一旦生成结果,它就会调用构建小部件的builder函数

AsyncSnapshot有3种状态:

  • connectionState.none=在此状态下,未来为空

  • connectionState.waiting=[future]不为空,但尚未完成

  • connectionState.done=[future]不为空,并且已完成。如果future成功完成,[AsyncSnapshot.data]将设置为future完成的值。如果完成时出现错误,[AsyncSnapshot.hasError]将为true

  • FutureBuilder是一个小部件,它将帮助您执行一些异步函数,并根据该函数的结果更新UI

    我列出了一些用例,为什么要使用FutureBuilder

  • 如果您想在异步任务之后呈现小部件,请使用它

  • 我们只需使用
    ConnectionState.waiting

  • 不需要任何自定义错误控制器。可以简单地处理错误
    dataSnapshot.error!=空

  • 因为我们可以在构建器中处理异步任务,所以不需要任何
    setState((){u isLoading=false;})

  • 当我们使用FutureBuilder小部件时,我们需要检查未来状态,即未来是否已解决,等等。有以下几种状态:

  • ConnectionState.none:
    这意味着future为null,initialData用作defaultValue

  • ConnectionState.active:
    表示未来不为空,但尚未解析

  • 连接状态。等待:
    这意味着未来正在解决,我们很快就会得到结果

  • ConnectionState.done:
    这意味着未来已经解决

  • 一个简单的实现

    这里OrdersProvider是一个提供程序类,fetchAndSetOrders()是该提供程序类的方法

    body: FutureBuilder(
            future: Provider.of<OrdersProvider>(context, listen: false)
                .fetchAndSetOrders(),
            builder: (context, dataSnapshot) {
              if (dataSnapshot.connectionState == ConnectionState.waiting) {
                return Center(
                  child: CircularProgressIndicator(),
                );
              } else {
                if (dataSnapshot.error != null) {
                  return Center(
                    child: Text('An error occured'),
                  );
                } else {
                  return Consumer<OrdersProvider>(
                    builder: (context, orderData, child) => ListView.builder(
                      itemCount: orderData.orders.length,
                      itemBuilder: (context, i) => OrderItem(orderData.orders[i]),
                    ),
                  );
                }
              }
            },
          ),
    
    body:FutureBuilder(
    future:Provider.of(上下文,侦听:false)
    .fetchAndSetOrders(),
    生成器:(上下文,数据快照){
    if(dataSnapshot.connectionState==connectionState.waiting){
    返回中心(
    子对象:CircularProgressIndicator(),
    );
    }否则{
    如果(dataSnapshot.error!=null){
    返回中心(
    子项:文本(“发生错误”),
    );
    }否则{
    退货消费者(
    生成器:(上下文、orderData、子项)=>ListView.builder(
    itemCount:orderData.orders.length,
    itemBuilder:(context,i)=>OrderItem(orderData.orders[i]),
    ),
    );
    }
    }