Reputation: 25
I am implementing map in flutter, I want it to show user current location as soon as it get launched, but getting error saying "Null check operator used on a null value" after few second the error disappear and it shows the current user location on a map. Why it first call currentLocation as null and then shows the current user location here are the codes
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class Usermap extends StatefulWidget {
const Usermap({Key? key}) : super(key: key);
@override
_UsermapState createState() => _UsermapState();
}
class _UsermapState extends State<Usermap> {
LatLng? currentPosition;
final Completer<GoogleMapController> _controller = Completer();
Set<Marker> markers = {};
@override
void initState() {
getCurrentPosition();
super.initState();
}
Future getCurrentPosition() async {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
setState(() {
if (position != null) {
currentPosition = LatLng(position.latitude, position.longitude);
markers.add(Marker(
markerId: const MarkerId('12'),
position: currentPosition!,
infoWindow: const InfoWindow(title: 'am here')));
} else {
print('error');
}
});
}
@override
Widget build(BuildContext context) {
final height = MediaQuery.of(context).size.height;
final width = MediaQuery.of(context).size.width;
return SizedBox(
height: height,
width: width,
child: Scaffold(
body: Stack(
children: [
GoogleMap(
initialCameraPosition:
CameraPosition(target: currentPosition!, zoom: 15),
myLocationEnabled: true,
myLocationButtonEnabled: false,
mapType: MapType.normal,
zoomControlsEnabled: false,
zoomGesturesEnabled: true,
markers: markers,
onMapCreated: (GoogleMapController controller) {
setState(() {
_controller.complete(controller);
});
}),
SafeArea(
child: Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ClipOval(
child: Material(
color: Colors.blue[100], // button color
child: InkWell(
splashColor: Colors.blue, // inkwell color
child: const SizedBox(
width: 50,
height: 50,
child: Icon(Icons.add),
),
onTap: () async {
final GoogleMapController mapController =
await _controller.future;
mapController.animateCamera(
CameraUpdate.zoomIn(),
);
},
),
),
),
const SizedBox(height: 20),
ClipOval(
child: Material(
color: Colors.blue[100], // button color
child: InkWell(
splashColor: Colors.blue, // inkwell color
child: const SizedBox(
width: 50,
height: 50,
child: Icon(Icons.remove),
),
onTap: () async {
final GoogleMapController mapController =
await _controller.future;
mapController.animateCamera(
CameraUpdate.zoomIn(),
);
},
),
),
)
],
),
),
),
SafeArea(
child: Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.only(right: 10.0, bottom: 10.0),
child: ClipOval(
child: Material(
color: Colors.orange[100], // button color
child: InkWell(
splashColor: Colors.orange, // inkwell color
child: const SizedBox(
width: 56,
height: 56,
child: Icon(Icons.my_location),
),
onTap: () {},
),
),
),
),
),
),
],
),
));
}
}
Upvotes: 0
Views: 1071
Reputation: 61
Okay, so you have used a null check operator in your build
method as such
...
CameraPosition(target: currentPosition!, zoom: 15),
...
which implies that currentPosition is not null for sure, which is not true for the first build of the widget.
In order to fix this, you should either initialize the currentPosition variable in initState() to some default location, or even better you should check if currentPosition is null, and create an appropriate widget as such:
@override
Widget build(BuildContext context) {
if(currentPosition == null){
return CircularProgressIndicator();
}
else{
return ... <- your code goes here
}
Upvotes: 1