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 如何在小部件构建方法中调用async属性_Dart_Flutter - Fatal编程技术网

Dart 如何在小部件构建方法中调用async属性

Dart 如何在小部件构建方法中调用async属性,dart,flutter,Dart,Flutter,我不熟悉颤振和飞镖,我正在尝试构建一个颤振应用程序,在屏幕上显示设备信息。为此,我尝试使用以下库:“设备信息”: 在MyApp类的“build”方法中,我试图实例化“device_info”包中的对象,并调用一个碰巧是异步属性的属性。由于默认的构建方法不是异步的,因此如何在构建方法中调用此属性?以下是我的代码: class MyApp extends StatelessWidget { @override Widget build(BuildContext context) {

我不熟悉颤振和飞镖,我正在尝试构建一个颤振应用程序,在屏幕上显示设备信息。为此,我尝试使用以下库:“设备信息”:

在MyApp类的“build”方法中,我试图实例化“device_info”包中的对象,并调用一个碰巧是异步属性的属性。由于默认的构建方法不是异步的,因此如何在构建方法中调用此属性?以下是我的代码:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
    AndroidDeviceInfo androidDeviceInfo = await deviceInfoPlugin.androidInfo;
    return MaterialApp(
      title: 'My Device Info',
      home: Scaffold(
        appBar: AppBar(
          title: Text('My Device Info'),
        ),
        body: Center(
          child: Text('Device model:' + 'Moto'),
        ),
      ),
    );
  }
}

您可以使用wait/async(作者@Günter Zöchbauer说,根据dart的最新版本,不需要导入lib)

并在生成方法外调用函数

  _getAndroidDeviceInfo() async{
    AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
    print(androidInfo.device);
  }

   _get_iOS_DeviceInfo() async{
    IosDeviceInfo iosDeviceInfo = await deviceInfo.iosInfo;
    print(iosDeviceInfo.model);
  }
build()
需要同步结果,因此在
build()
中使用
async
/
wait
是不合适的


在异步结果不可用时返回占位符
Container()
的位置使用,或者将异步代码移动到
initState()
并在值可用时使用
setState
更新状态,以便再次执行
build

我建议您使用
FutureBuilder

import 'package:flutter/material.dart';

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // save in the state for caching!
  DeviceInfoPlugin _deviceInfoPlugin;

  @override
  void initState() {
    super.initState();
    _deviceInfoPlugin = DeviceInfoPlugin();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My Device Info',
      home: Scaffold(
        appBar: AppBar(
          title: Text('My Device Info'),
        ),
        body: FutureBuilder<AndroidDeviceInfo>(
          future: _deviceInfoPlugin.androidInfo,
          builder: (BuildContext context, AsyncSnapshot<AndroidDeviceInfo> snapshot) {
            if (!snapshot.hasData) {
              // while data is loading:
              return Center(
                child: CircularProgressIndicator(),
              );
            } else {
              // data loaded:
              final androidDeviceInfo = snapshot.data;
              return Center(
                child: Text('Android version: ${androidDeviceInfo.version}'),
              );
            }
          },
        ),
      ),
    );
  }
}

您不必为此导入
dart:async
。有一些类,如
StreamSubscription
Completer
。。。需要进口的地方。在以前的版本中,当您使用类型
Stream
Future
时,它是必需的,但在最新的Dart中,这些类型是从
Dart:core
导出的,因此可以自动使用。@GünterZöchbauer-感谢您的帮助。我会更新答案如果你必须返回到构建方法怎么办??异步方法应该始终返回未来的对象。这不是与问题匹配的正确答案。再次查看问题中的问题描述。问题是如何在无状态小部件中调用aync函数。来自@boformer的回答是正确的,即使在这种情况下使用无状态小部件是不可能的。谢谢你,boformer,我能够使用你建议的代码更改构建应用程序。但是,当我在emulator上运行应用程序时,${androidDeviceInfo.version}的值打印文本“AndroidBuilderVersion的实例”。我在这里遗漏了什么吗?没关系,我通过访问AndroidBuildVersion对象的属性修复了上述问题。非常感谢。你救了我在凌晨4点发疯!initState()+setState是FutureBuilder在父对象需要来自其他建筑对象的数据来构建子对象的情况下的最佳选择。好的一面是,initState和setState都不能是异步的…您可以从
initState
调用异步的方法。只需将您试图执行的代码移动到另一个函数,并从
initState
调用它即可。无需在
initState()
中等待它。异步执行完成后,只需调用
setState(…)
import 'package:flutter/material.dart';

class FooWidget extends StatefulWidget {
  @override
  _FooWidgetState createState() => _FooWidgetState();
}

class _FooWidgetState extends State<FooWidget> {
  Future<int> _bar;

  @override
  void initState() {
    super.initState();
    _bar = doSomeLongRunningCalculation();
  }

  void _retry() {
    setState(() {
      _bar = doSomeLongRunningCalculation();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        FutureBuilder<int>(
          future: _bar,
          builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
            if (snapshot.hasData) {
              return Text('The answer to everything is ${snapshot.data}');
            } else {
              return Text('Calculating answer...');
            }
          },
        ),
        RaisedButton(
          onPressed: _retry,
          child: Text('Retry'),
        )
      ],
    );
  }
}

Future<int> doSomeLongRunningCalculation() async {
  await Future.delayed(Duration(seconds: 5)); // wait 5 sec
  return 42;
}