我在处理async
数据(即用户GPS协调)输入时遇到问题。
我将我的应用简化为下面的计算器应用,该应用通过provider
管理状态(双精度)。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(ProviderApp());
class ProviderApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MyProvider>(
create: (_) => MyProvider(1.55),
child: CalApp(),
);
}
}
class CalApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final myProvider = Provider.of<MyProvider>(context);
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(myProvider.getMyProvider().toString()),
RaisedButton(
child: Text('increase 10%'),
onPressed: () {
myProvider.userProvider();
},
)
],
),
),
),
);
}
}
class MyProvider with ChangeNotifier {
double _myProvider;
MyProvider(this._myProvider);
double getMyProvider() => _myProvider;
void userProvider() {
_myProvider *= 1.1;
notifyListeners();
}
}
现在,我不想使用初始的double
1.55,而是想将用户当前的纬度用作Geolocator
的一次性输入。
1)我的第一个解决方案是将纬度通过ProviderApp
传递到FutureBuilder
。
这有点奏效,但是在获得最终页面之前,有一个错误页面,指出FutureBuilder
正在传递null
。
如果我给FutureBuilder一个initialData: Position(latitude: 20.0),
,那么提供商将只收取20.0并忽略以下纬度数据。
import 'dart:ffi';
import 'dart:async';
import 'package:geolocator/geolocator.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(TreeTop());
class TreeTop extends StatelessWidget {
@override
Widget build(BuildContext context) {
Gps gps = Gps();
return FutureBuilder(
future: gps.currentPosition,
// initialData: Position(latitude: 20.0),
builder: (context, snapshot) {
return ProviderApp(snapshot.data.latitude);
},
);
}
}
class ProviderApp extends StatelessWidget {
final double myNum;
ProviderApp(this.myNum);
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MyProvider>(
create: (_) => MyProvider(myNum),
child: CalApp(),
);
}
}
class CalApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final myProvider = Provider.of<MyProvider>(context);
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(myProvider.getMyProvider().toString()),
RaisedButton(
child: Text('increase 10%'),
onPressed: () {
myProvider.userProvider();
},
)
],
),
),
),
);
}
}
class MyProvider with ChangeNotifier {
double _myProvider;
MyProvider(this._myProvider);
double getMyProvider() => _myProvider;
void userProvider() {
_myProvider *= 1.1;
notifyListeners();
}
}
class Gps {
//
// get * one-time * user coordination via geolocator
//
Future<Position> currentPosition = Geolocator().getCurrentPosition(
desiredAccuracy: LocationAccuracy.bestForNavigation,
locationPermissionLevel: GeolocationPermission.locationWhenInUse);
}
2),然后在from Setting provider value in FutureBuilder寻求RémiRousselet的解决方案,
我试图修改MyProvider
构造函数,但由于无法使构造函数异步而失败。
3)现在我正在考虑制作一个FutureProvider
注入ChangeNotifierProvider
中,但我真的对此表示怀疑。
在这一点上,我觉得我正在与框架和软件包进行斗争,而不是让它们来帮助我,所以我希望也许您能给我一些建议。
答案 0 :(得分:0)
睡一觉后,我觉得可以简单地通过检查快照来解决此问题。
return snapshot.hasData
? ProviderApp(snapshot.data.latitude)
: Center(child: CircularProgressIndicator());