我是Flutter和Dart的新手,我正在尝试构建一个Flutter应用,该应用在屏幕上显示设备信息。为此,我正在尝试使用以下库:'{_3}}
在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'),
),
),
);
}
}
答案 0 :(得分:3)
我建议您使用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
或Future
时,请记住可以随时重新构建封闭的小部件(例如,因为设备已旋转或显示了键盘, )。这意味着build
方法被再次调用。
在这种特殊情况下,这不是问题,因为该插件会缓存该值并立即返回它,但是通常,您永远不要在Future
方法内创建或获取build
。而是从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;
}
答案 1 :(得分:1)
您可以使用 await / async 来实现它(通过@GünterZö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);
}
答案 2 :(得分:1)
build()
需要同步结果,因此在async
中使用await
/ build()
是不合适的。
在尚未获得异步结果的情况下,使用FutureBuilder返回占位符Container()
,或者在出现以下情况时将异步代码移至initState()
并使用setState
更新状态该值可用于再次执行build
。