Reputation: 43
I am trying to project on screen the address of the center of the google map in Flutter with the help of GeoCode but I am having problem dealing with Futures. Here is my code:
class _ManageLocationPage extends State<ManageLocationPage> {
final List<Marker> _markers = [];
late GeoPoint chosenLocation;
late final Future<Address> _getAddressFuture;
Future<Address> getAddress(GeoPoint currentLocation) async {
GeoCode geoCode = GeoCode();
return await geoCode.reverseGeocoding(latitude: currentLocation.latitude, longitude: currentLocation.longitude);
}
@override
void initState(){
super.initState();
chosenLocation = widget.startSpot;
_getAddressFuture = getAddress(chosenLocation);
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _getAddressFuture,
builder: (context, snapshot) {
if (snapshot.hasData) {
// future is completed with data, you can build
Address addr = snapshot.data as Address;
return Stack(
alignment: Alignment.center,
children: [
GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(
widget.startSpot.latitude, widget.startSpot.longitude),
zoom: 18),
zoomControlsEnabled: false,
compassEnabled: false,
indoorViewEnabled: true,
mapToolbarEnabled: false,
onMapCreated: (controller) {
final marker = Marker(
markerId: MarkerId('0'),
position: LatLng(
widget.startSpot.latitude, widget.startSpot.longitude),
);
_markers.add(marker);
},
onCameraMove: (position) {
chosenLocation = GeoPoint(position.target.latitude, position.target.longitude);
setState(() {
_markers.first =
_markers.first.copyWith(positionParam: position.target);
});
},
),
Positioned(
top: Dimensions.height45 + Dimensions.height10,
left: Dimensions.width20,
right: Dimensions.width20,
child: Container(
padding: EdgeInsets.symmetric(horizontal: Dimensions.width10),
height: 50,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(Dimensions.radius20/2),
boxShadow: [
BoxShadow(
blurRadius: 10,
spreadRadius: 7,
offset: Offset(1, 10),
color: Colors.grey.withOpacity(0.2)
)
]
),
child: Row(
children: [
Icon(Icons.storefront, size: 25, color: AppColors.iconColor1),
SizedBox(width: Dimensions.width10,),
Expanded(child: SmallText(text: addr.streetAddress.toString(),)),
],
)
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 42),
child: Icon(
Icons.location_on,
color: AppColors.mainColor,
size: 50,
),
),
],
),
],
);
} else if (snapshot.hasError) {
// handler errors
return const Text('Error');
}
else {
// future is not completed yet, display a progress indicator
return const Center(child: CircularProgressIndicator());
}
});
}
}
When I try to run, I get the error type Future<Address> is not a subtype of type Address
.
When I don't use geocode and just display the latitude and longitude via printing chosenLocation
, everything is fine and going well.
Upvotes: 0
Views: 121
Reputation: 9744
In the FutureBuilder
you need to check the status of the future (whether it is completed) before you build the GoogleMap
. Currently, most of the times you try to build before the future completes.
Also, it is advised to store the future function in a member and not directly call it in the build method, so that it is not called multiple times.
Try the following:
class _ManageLocationPage extends State<ManageLocationPage> {
final List<Marker> _markers = [];
late GeoPoint chosenLocation;
late final Future<Address> _getAddressFuture;
Future<Address> getAddress(GeoPoint currentLocation) async {
GeoCode geoCode = GeoCode();
return await geoCode.reverseGeocoding(latitude:
currentLocation.latitude,
longitude: currentLocation.longitude);
}
@override
void initState(){
super.initState();
chosenLocation = widget.startSpot;
_getAddressFuture = getAddress(chosenLocation);
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _getAddressFuture,
builder: (context, snapshot) {
if (snapshot.hasData) {
// future is completed with data, you can build
return Stack(...);
} else if (snapshot.hasError) {
// handler errors
return const Text('Error');
}
else {
// future is not completed yet, display a progress indicator
return const Center(child: CircularProgressIndicator());
}
});
}
Upvotes: 0