我得到了下面的geolocation.dart
文件,该文件可以完美地用作独立的小部件:
import 'package:flutter/material.dart';
import 'package:location/location.dart';
import 'package:flutter/services.dart';
import 'package:simple_permissions/simple_permissions.dart';
class LocationField extends StatefulWidget {
const LocationField({
this.fieldKey,
this.onSaved,
});
final Key fieldKey;
final FormFieldSetter<String> onSaved;
@override
_LocationFieldState createState() => _LocationFieldState();
}
class _LocationFieldState extends State<LocationField> {
Location _location = new Location();
final lat = TextEditingController();
final lon = TextEditingController();
// @override
// void initState() {
// super.initState();
// lat.addListener(_addLatValue);
// lon.addListener(_addLonValue);
//}
@override
Widget build(BuildContext context) {
return Row(
textDirection: TextDirection.rtl,
children: <Widget>[
FlatButton(
child: const Icon(Icons.my_location),
onPressed: () => _getLocation(),
),
Expanded(child: Column(
textDirection: TextDirection.ltr,
children: <Widget>[
TextFormField(
controller: lat,
decoration: InputDecoration(
prefixIcon: Text("Latittude: ")
),
),
TextFormField(
controller: lon,
decoration: InputDecoration(
prefixIcon: Text("Longitude: ")
),
)
])
)
],
);
}
_getLocation() async {
Map<String, double> location;
var error = null;
try {
await SimplePermissions.requestPermission(Permission.AccessFineLocation);
location = await _location.getLocation();
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
error = 'Permission denied';
} else if (e.code == 'PERMISSION_DENIED_NEVER_ASK') {
error =
'Permission denied - please ask the user to enable it from the app settings';
}
location = null;
}
print("error $error");
setState(() {
lat.text = ('${location["latitude"]}');
lon.text = ('${location["longitude"]}');
});
}
}
并显示以下内容,单击位置图标时,位置坐标将出现在下面,
我还可以将其作为小部件插入我的主应用程序中,例如:
class _SignUpPageState extends State<SignUpPage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
body: Form(
key: _formKey,
child: Column(
children: <Widget>[
LocationField(),
RaisedButton(
onPressed: signUp,
child: Text('Sign up'),
),
],
)
),
);
}
void signUp() {
// what to write here to get the geolocation points lat/lon printed?
}
我的问题是:单击signup
按钮后如何获取经纬度打印的地理位置点,如何从子小部件中获取2个字段的值?
答案 0 :(得分:0)
在Flutter中,使用InheritedWidget
&co。将状态沿小部件树向下传递非常容易,而向上传递数据实际上涉及一些思考。
类似于您使用的TextEditingController
,您可以创建一个保存位置数据的LocationController
:
class LocationController {
Location _location = Location();
get location => _location;
set location(Location val) {
_location = val;
if (onChanged != null) _onChanged(val);
}
VoidCallback _onChanged;
}
然后可以将此控制器传递给LocationField
,如下所示:
class LocationField extends StatefulWidget {
LocationField({
this.fieldKey,
@required this.controller,
this.onSaved,
});
final Key fieldKey;
final LocationController controller;
final FormFieldSetter<String> onSaved;
@override
_LocationFieldState createState() => _LocationFieldState();
}
class _LocationFieldState extends State<LocationField> {
final lat = TextEditingController();
final lon = TextEditingController();
@override
void initState() {
super.initState();
widget.controller._onChanged = (location) => setState(() {
lat.text = ('${location["latitude"]}');
lon.text = ('${location["longitude"]}');
});
lat.addListener(_addLatValue);
lon.addListener(_addLonValue);
}
@override
Widget build(BuildContext context) { ... }
_getLocation() async {
String error;
try {
await SimplePermissions.requestPermission(Permission.AccessFineLocation);
widget.controller.location = await _location.getLocation();
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
error = 'Permission denied';
} else if (e.code == 'PERMISSION_DENIED_NEVER_ASK') {
error =
'Permission denied - please ask the user to enable it from the app settings';
}
location = null;
}
print("error $error");
}
}
然后,在树上的小部件中,您可以访问控制器以检索位置:
class _SignUpPageState extends State<SignUpPage> {
LocationController controller = LocationController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Form(
key: _formKey,
child: Column(
children: <Widget>[
LocationField(controller: controller),
RaisedButton(onPressed: signUp, child: Text('Sign up')),
],
)
),
);
}
void signUp() {
final location = controller.location;
}
}
另一个好处是,您可以从树中的小部件中设置controller
的{{1}},location
将自动重建以反映该更改。