我是Flutter和Dart的新手,我正在尝试构建一个Flutter应用程序,以在屏幕上显示设备信息。为此,我尝试使用以下库:’device_info’,网址为:https : //pub.dartlang.org/packages/device_info#-readme- tab-
在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'), ), ), ); } }
我建议您使用FutureBuilder:
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}'), ); } }, ), ), ); } }
通常,在使用FutureBuilder或Futures时,必须记住可以随时重新构建封闭的小部件(例如,因为设备已旋转或显示了键盘)。这意味着将build再次调用该方法。
Future
build
在这种特殊情况下,这不是问题,因为该插件会缓存该值并立即返回它,但通常来说,您永远不要创建或获取Future该build方法的内部内容。相反,您可以通过initState点击事件处理程序或点击事件处理程序执行此操作:
initState
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; }