I want to initialize the value of _lastMapPosition from the session variables but In my case the builds method runs before intistate method. Is there a simple way to initialize it before build widget method? I am new to flutter kindly provide complete details. I have tried futurebuilder but i think I tried it all wrong.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:permission/permission.dart';
import 'package:flutter_session/flutter_session.dart';
class GmyApp extends StatefulWidget {
const GmyApp({Key key}) : super(key: key);
@override
_GmyApp createState() => _GmyApp();
}
class _GmyApp extends State<GmyApp> {
var latitude_data;
var longitude_data;
Completer<GoogleMapController> _controller = Completer();
static const LatLng _center = const LatLng(10.8505, 76.2711);
final Set<Marker> _markers = {};
LatLng _lastMapPosition= _center;
MapType _currentMapType = MapType.normal;
void _onMapTypeButtonPressed() {
setState(() {
_currentMapType = _currentMapType == MapType.normal
? MapType.satellite
: MapType.normal;
});
}
void _onAddMarkerButtonPressed() {
setState(() {
_markers.add(Marker(
// This marker id can be anything that uniquely identifies each marker.
markerId: MarkerId(_lastMapPosition.toString()),
position: _lastMapPosition,
infoWindow: InfoWindow(
title: 'Your last location',
snippet: 'Location Refreshed every 1 hour',
),
icon: BitmapDescriptor.defaultMarker,
));
});
}
void _onCameraMove(CameraPosition position) {
_lastMapPosition = position.target;
}
void _onMapCreated(GoogleMapController controller) {
_controller.complete(controller);
}
@override
void initState() {
// TODO: implement initState
super.initState();
setGps();
}
Future setGps() async {
bool visible = false;
print('I am in GPS setter*');
// var session = FlutterSession();
latitude_data = await FlutterSession().get('lat');
longitude_data = await FlutterSession().get('longi');
print('User logi Id is in GPS* $longitude_data');
print('User lat is in GPS* $latitude_data');
LatLng center1=LatLng(latitude_data, longitude_data);
print('Lat .lat is in GPS $center1');
_lastMapPosition = center1;
print('Lat .lat lastMap Position is $_lastMapPosition');
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Your Current Location is'),
backgroundColor: Colors.green[700],
),
body: Stack(
children: <Widget>[
GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: _lastMapPosition,
zoom: 11.0,
),
mapType: _currentMapType,
markers: _markers,
onCameraMove: _onCameraMove,
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Align(
alignment: Alignment.topRight,
child: Column(
children: <Widget> [
FloatingActionButton(
onPressed: _onMapTypeButtonPressed,
heroTag: "btn1",
materialTapTargetSize: MaterialTapTargetSize.padded,
backgroundColor: Colors.green,
child: const Icon(Icons.map, size: 36.0),
),
SizedBox(height: 16.0),
FloatingActionButton(
onPressed: _onAddMarkerButtonPressed,
heroTag: "btn2",
materialTapTargetSize: MaterialTapTargetSize.padded,
backgroundColor: Colors.green,
child: const Icon(Icons.add_location, size: 36.0),
),
],
),
),
),
],
),
),
);
}
}
2
Answers
Because your data gets loaded asynchronously build will be called before your data gets loaded.
there are a few solutions the best would be to use a state management solution then check for the current state of your data to show or hide the related widgets.
but for a quick fix you can make
_lastMapPosition
nullableLatLng? _lastMapPosition;
and don’t give it an initial value, then before GoogleMap widget check if the data is loaded and if not show a loading indicatorNow when your data gets loaded inside
setGps
usesetState
to rebuild the ui with the new datai still recommend to use a state management solution which can make you code way more readable and predictable
Just add setState method at your setGps() method