将异步数据(GPS 协调)从 FutureBuilder 传递给提供者/设置异步构造函数
Posted
技术标签:
【中文标题】将异步数据(GPS 协调)从 FutureBuilder 传递给提供者/设置异步构造函数【英文标题】:Passing async data (GPS coordination) from FutureBuilder to Provider / Setting async constructor 【发布时间】:2020-04-22 15:16:18 【问题描述】:我在处理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) 我的第一个解决方案是通过FutureBuilder
将纬度向下传递到ProviderApp
。
这有点工作,但在获得最后一页之前,有一个错误页面显示 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émi Rousselet 的解决方案,
我尝试修改 MyProvider
构造函数但失败了,因为我无法使构造函数异步。
3) 现在我正在考虑将FutureProvider
注入ChangeNotifierProvider
,但我真的很怀疑。
在这一点上,我觉得我在与框架和包作斗争,而不是让它们帮助我,所以我希望你能给我一些建议。
【问题讨论】:
【参考方案1】:睡了一会儿,感觉可以通过查看snapshot.data简单解决
return snapshot.hasData
? ProviderApp(snapshot.data.latitude)
: Center(child: CircularProgressIndicator());
【讨论】:
以上是关于将异步数据(GPS 协调)从 FutureBuilder 传递给提供者/设置异步构造函数的主要内容,如果未能解决你的问题,请参考以下文章