Error:
location.dart failed assertion: .... 'latitude != null': is not true.
Apparently, the answer is here:
Flutter - Google Maps doesn´t wait to Location
However, none of these things worked for me.
Attempt:
show an empty Container() while lat and lng is null...
I have no clue what on earth this is... ==?? like with python?
lat == null || lng == null
? Container()
My guess is this guy wants me to assign lat and lng to null and put google map into a container. Here goes nothing:
var lat = null;
var lng = null;
I converted my sizedbox to a container and changed the initial camera position:
before:
SizedBox(
height: 350,
child: GoogleMap(
markers: Set.from(markers),
initialCameraPosition: _myLocation,
myLocationEnabled: true,
compassEnabled: true,
myLocationButtonEnabled: true,
mapType: MapType.normal,
onMapCreated: (GoogleMapController controller) {
controller.setMapStyle(Utils.mapStyles);
}),
after:
Container(
height: 350,
child: GoogleMap(
markers: Set.from(markers),
initialCameraPosition: CameraPosition(
target: LatLng(lat, lng),
zoom: 15.0),
myLocationEnabled: true,
compassEnabled: true,
myLocationButtonEnabled: true,
mapType: MapType.normal,
onMapCreated: (GoogleMapController controller) {
controller.setMapStyle(Utils.mapStyles);
}),
),
Result:
Failed assertion: 'latitude != null': is not true.
The program won't even compile now. to poke a bit, I changed the target to: target: LatLng(null, null),
Same error. Nothing has changed.
<wiped everything, started over>
"you can display a loader until you get your location"
Didn't work.
This is how I'm calling my longitude and latitude points from Google sheets. I'm trying to plot them on buttonpress:
Future<void> _plotCurrent() async {
Map<double,double> m = (await sheet.values.map.column(3, fromRow:2)).map((key, value)=>
MapEntry(double.parse(key), double.parse(value)));
Map<double,double> m2 = (await sheet.values.map.column(4, fromRow:2)).map((key, value)=>
MapEntry(double.parse(key), double.parse(value)));
Iterable _markers = Iterable.generate(10, (index) {
LatLng latLngMarker = LatLng(m["test$index"], m2["test$index"]);
return Marker(markerId: MarkerId("test$index"),position: latLngMarker);
});
setState(() {
markers = _markers;
});
}
I've read some stuff about having to change my Widget build tree into a Future type. However, I'm still terrible with Dart. I don't know to do it. Could this work? Here's the start of my Widget:
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text(widget.title, style: TextStyle(fontSize: 11)),
centerTitle: true,
),
body:
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
Please help. Thank you.
Edit:
This makes no sense.. Is geolocator messing this up or something? Here's what I have now:
#override
initState() {
super.initState();
getLocation();
}
var lng, lat;
Future getLocation() async {
Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
setState(() {
lat = position.latitude;
lng = position.longitude;
print(lng);
});
}
#override
Widget build(BuildContext context) {
if (lat == null || lng == null) {
return Container();
}
Container(
height: 350,
child: GoogleMap(
markers: Set.from(markers),
initialCameraPosition: CameraPosition(
target: LatLng(lat, lng),
zoom: 15.0),
myLocationEnabled: true,
compassEnabled: true,
myLocationButtonEnabled: true,
mapType: MapType.normal,
onMapCreated: (GoogleMapController controller) {
controller.setMapStyle(Utils.mapStyles);
}),
);
return Scaffold(
key: _scaffoldKey,
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text(widget.title, style: TextStyle(fontSize: 11)),
centerTitle: true,
),
body:
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Form(
key: _formKey,
child: Padding(
first problem is, my map isn't showing up anymore. I can print coordinates... So, I don't get why the error is still showing and everything is crashing after I press plot. Anybody?
Edit 2:
This may have something to do with my error:
The relevant error-causing widget was: MyHomePage
file:///C:/Users/xxx/Desktop/xxxxx/xxxx-xxx/lib/main.dart:92:13 When
the exception was thrown, this was the stack:
points to this widget:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'xx',
theme: ThemeData(
primarySwatch: colorCustom,
hintColor: Colors.white,
canvasColor: colorCustom,
backgroundColor: Colors.red,
),
home: MyHomePage(title: 'xx'),
);
}
}
I don't have enough experience with Dart to know what's wrong with having a homepage with a title separate from the rest of my widgets. Is this a bad thing?
I moved my widget elsewhere and applied the container. My app won't start with the lat == null || lng == null statement and throws the following error:
The following assertion was thrown building GoogleMap(state:
_GoogleMapState#81111): No Directionality widget found.
I think the problem is I have too much garbage loading in. I'm lost.
void main() => runApp(
RestartWidget(child: MyApp()),
);
class RestartWidget extends StatefulWidget {
RestartWidget({this.child});
final Widget child;
static void restartApp(BuildContext context) {
context.findAncestorStateOfType<_RestartWidgetState>().restartApp();
}
#override
_RestartWidgetState createState() => _RestartWidgetState();
}
class _RestartWidgetState extends State<RestartWidget> {
Key key = UniqueKey();
void restartApp() {
setState(() {
key = UniqueKey();
});
}
#override
Widget build(BuildContext context) {
return KeyedSubtree(
key: key,
child: widget.child,
);
}
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'xxxxxxx',
theme: ThemeData(
primarySwatch: colorCustom,
hintColor: Colors.white,
canvasColor: colorCustom,
backgroundColor: Colors.red,
),
home: MyHomePage(title: 'xxxxxxx'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _formKey = GlobalKey<FormState>();
final _scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
etc... I'm so lost in all of these Widgets. Something is causing my location to be null. I don't know. Anybody?
When dealing with async data loading, you need to have a placeholder container until your data gets loaded. In this case that's lat and long parameters.
Widget methodReturningWidget() {
// In case your data is not ready, return empty container
if (lat == null || long == null) {
return Container();
}
// In case your data is present, return GoogleMap object
return Container(
height: 350,
child: GoogleMap(
markers: Set.from(markers),
initialCameraPosition: CameraPosition(
target: LatLng(lat, long),
zoom: 15.0),
myLocationEnabled: true,
compassEnabled: true,
myLocationButtonEnabled: true,
mapType: MapType.normal,
onMapCreated: (GoogleMapController controller) {
controller.setMapStyle(Utils.mapStyles);
}),
);
}
Part of the code that is crashing your app is this here LatLng(lat, long) that tries to create object, but it's parameters lat and long are null.
I don't have an approximate answer. However, I do believe I found the cause of this.
Map<double, double> m = (await sheet.values.map.column(3, fromRow: 2)).map((
key, value) =>
MapEntry(double.parse(key), double.parse(value)));
Map<double, double> m2 = (await sheet.values.map.column(4, fromRow: 2))
.map((key, value) =>
MapEntry(double.parse(key), double.parse(value)));
print(_markers);
setState(() {
Iterable _markers = Iterable.generate(10, (index) {
LatLng latLngMarker = LatLng(m["test$index"], m2["test$index"]);
return Marker(markerId: MarkerId("test$index"), position: latLngMarker);
});
markers = _markers;
In short, I'm calling the lat and long improperly somehow and it's throwing the error. I verified this by plotting a single point from my current location. Doing so worked without any issues. I'll have to research how to call my columns (coordinates) properly. If anyone has any insight, please let me know. Thanks
Edit: I think I found the problem.
my m and m2 are printing keys and values...!! The keys are messing everything up.
Related
I am trying to change from normal to satellite when pressing a button as shown below, but i get an error that setMapType does not exist.
mapController.setMapType(MapType.satellite);
Anyone knows what I am doing wrong?
Create a MapType variable:
MapType _currentMapType = MapType.normal;
Reference this variable when calling your Google Map widget:
googleMap = new GoogleMap(
mapType: _currentMapType,
//etc
Create a floating button widget to toggle map types:
floatingActionButton: FloatingActionButton(
child: Icon(Icons.layers),
onPressed: ()=>
{
setState(() {
_currentMapType = (_currentMapType == MapType.normal) ? MapType.satellite : MapType.normal;
});
},
heroTag: null,
),
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:search_map_place/search_map_place.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
String apiKEY;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Search Map Place Demo',
home: MapSample(),
);
}
}
class MapSample extends StatefulWidget {
#override
State<MapSample> createState() => MapSampleState();
}
class MapSampleState extends State<MapSample> {
Completer<GoogleMapController> _mapController = Completer();
final CameraPosition _initialCamera = CameraPosition(
target: LatLng(-20.3000, -40.2990),
zoom: 14.0000,
);
var maptype = MapType.normal;
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
body: Stack(
children: <Widget>[
GoogleMap(
mapType: maptype,
initialCameraPosition: _initialCamera,
onMapCreated: (GoogleMapController controller) {
_mapController.complete(controller);
},
),
],
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.white,
foregroundColor: Colors.black,
child: const Icon(Icons.my_location),
onPressed: () {
setState(() {
this.maptype=MapType.satellite;
});
},
),
);
}
}
I need to load maps in background because when I hit the tab with maps.dart for the first time, map is loading. It is looking bad so I want to use FutureBuilder to show CircularProgressIndicator() but I have no idea how to do this.
I know how to do it with Lists but in this case...
This maps.dart code:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class Maps extends StatefulWidget {
#override
_MapsState createState() => _MapsState();
}
class _MapsState extends State<Maps> with AutomaticKeepAliveClientMixin {
Completer<GoogleMapController> _controller = Completer();
#override
void initState() {
super.initState();
}
double zoomValue = 9.0;
#override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
body: Stack(
children: <Widget>[
_buildGoogleMap(context),
_zoomMinusFunction(),
_zoomPlusFunction(),
],
),
);
}
Widget _zoomMinusFunction() {
return Align(
alignment: Alignment.topLeft,
child: IconButton(
icon: Icon(FontAwesomeIcons.searchMinus, color: Color(0xff6200ee)),
onPressed: () {
zoomValue--;
_minus(zoomValue);
}),
);
}
Widget _zoomPlusFunction() {
return Align(
alignment: Alignment.topRight,
child: IconButton(
icon: Icon(FontAwesomeIcons.searchPlus, color: Color(0xff6200ee)),
onPressed: () {
zoomValue++;
_plus(zoomValue);
}),
);
}
Future<void> _minus(double zoomValue) async {
final GoogleMapController controller = await _controller.future;
controller.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(target: LatLng(x, y), zoom: zoomValue)));
}
Future<void> _plus(double zoomValue) async {
final GoogleMapController controller = await _controller.future;
controller.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(target: LatLng(x, y), zoom: zoomValue)));
}
Widget _buildGoogleMap(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: GoogleMap(
mapType: MapType.normal,
initialCameraPosition:
CameraPosition(target: LatLng(x, y), zoom: 9),
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
markers: {
aaa,
bbb,
},
),
);
}
#override
bool get wantKeepAlive => true;
}
Marker aaa = Marker(
markerId: MarkerId('aaa'),
position: LatLng(x, y),
infoWindow: InfoWindow(title: 'aaa', snippet: 'aaa'),
icon: BitmapDescriptor.defaultMarkerWithHue(
BitmapDescriptor.hueViolet,
),
);
Marker bbb = Marker(
markerId: MarkerId('bbb'),
position: LatLng(x, y),
infoWindow:
InfoWindow(title: 'bbb', snippet: 'bbb'),
icon: BitmapDescriptor.defaultMarkerWithHue(
BitmapDescriptor.hueViolet,
),
);
Sorry, I'm new to Flutter.
I know this is a little late, but if it still helps, this is what I have done.
_userLocation == null // If user location has not been found
? Center(
// Display Progress Indicator
child: CircularProgressIndicator(
backgroundColor: UniColors.primaryColour[500],
),
)
: GoogleMap(
// Show Campus Map
onMapCreated: _onMapCreated,
initialCameraPosition: // required parameter that sets the starting camera position. Camera position describes which part of the world you want the map to point at.
CameraPosition(
target: _userLocation,
zoom: defaultZoom,
tilt: 0.0),
scrollGesturesEnabled: true,
tiltGesturesEnabled: true,
trafficEnabled: false,
indoorViewEnabled: true,
compassEnabled: true,
rotateGesturesEnabled: true,
myLocationEnabled: true,
mapType: _currentMapType,
zoomGesturesEnabled: true,
cameraTargetBounds: new CameraTargetBounds(
new LatLngBounds(
northeast: uniCampusNE,
southwest: uniCampusSW,
),
),
minMaxZoomPreference:
new MinMaxZoomPreference(minZoom, maxZoom),
),
I'm using Flutter's Geolocator and Google Maps packages to determine a device's location. I utilize the Circular Progress Bar to wait for the current location to be determined. Once determined, Google Maps loads with the device's location identified.
When the application loads, the circular progress bar is displayed but the map is not loaded despite the notification being displayed and accepted to use location services; the app hangs on the circular progress bar. I don't believe this to be an API issue as I have had success loading the map with coordinates specified in InitialCameraPosition.
Is the device's location not being determined which is the cause for the map to not load with the location indicated?
I've tried running the app on both Android emulator and a physical device without success.
Android Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="smartkart.app.com.coffee">
<!-- io.flutter.app.FlutterApplication is an android.app.Application
that
calls FlutterMain.startInitialization(this); in its onCreate
method.
In most cases you can leave this as-is, but you if you want to
provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:name="io.flutter.app.FlutterApplication"
android:label="coffee"
android:icon="#mipmap/ic_launcher">
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="API KEY HERE"/>
<activity../>
Maps Screen
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
class FirstScreen extends StatefulWidget {
const FirstScreen({Key key}) : super(key: key);
#override
State<FirstScreen> createState() => _FirstScreen();
}
class _FirstScreen extends State<FirstScreen> {
GoogleMapController mapController;
var currentLocation;
#override
void initState(){
super.initState();
Geolocator().getCurrentPosition().then((currloc){
currentLocation = currloc;
});
}
#override
Widget build(BuildContext context) {
return currentLocation == null ? Container(
alignment: Alignment.center,
child: Center(
child: CircularProgressIndicator(),
),
):
Stack(
children: <Widget>[
GoogleMap(
initialCameraPosition:
CameraPosition(target: LatLng(currentLocation.latitude,
currentLocation.longitude), zoom: 10),
onMapCreated: _onMapCreated,
myLocationEnabled: true,
mapType: MapType.normal,
),
],
);
}
void _onMapCreated(GoogleMapController controller) {
setState(() {
mapController = controller;
});
}
}
I expect the notification to use location services to appear while the circular progress bar is displayed. Once the location is determined, the InitialCameraPosition displays the device's location on the map.
Try the following code as a solution. You can modify the map widget to your use case:
import 'package:flutter/cupertino.dart';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class Map extends StatefulWidget {
#override
_MapState createState() => _MapState();
}
class _MapState extends State<Map> {
Completer<GoogleMapController> controller1;
//static LatLng _center = LatLng(-15.4630239974464, 28.363397732282127);
static LatLng _initialPosition;
final Set<Marker> _markers = {};
static LatLng _lastMapPosition = _initialPosition;
#override
void initState() {
super.initState();
_getUserLocation();
}
void _getUserLocation() async {
Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
List<Placemark> placemark = await Geolocator().placemarkFromCoordinates(position.latitude, position.longitude);
setState(() {
_initialPosition = LatLng(position.latitude, position.longitude);
print('${placemark[0].name}');
});
}
_onMapCreated(GoogleMapController controller) {
setState(() {
controller1.complete(controller);
});
}
MapType _currentMapType = MapType.normal;
void _onMapTypeButtonPressed() {
setState(() {
_currentMapType = _currentMapType == MapType.normal
? MapType.satellite
: MapType.normal;
});
}
_onCameraMove(CameraPosition position) {
_lastMapPosition = position.target;
}
_onAddMarkerButtonPressed() {
setState(() {
_markers.add(
Marker(
markerId: MarkerId(_lastMapPosition.toString()),
position: _lastMapPosition,
infoWindow: InfoWindow(
title: "Pizza Parlour",
snippet: "This is a snippet",
onTap: (){
}
),
onTap: (){
},
icon: BitmapDescriptor.defaultMarker));
});
}
Widget mapButton(Function function, Icon icon, Color color) {
return RawMaterialButton(
onPressed: function,
child: icon,
shape: new CircleBorder(),
elevation: 2.0,
fillColor: color,
padding: const EdgeInsets.all(7.0),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: _initialPosition == null ? Container(child: Center(child:Text('loading map..', style: TextStyle(fontFamily: 'Avenir-Medium', color: Colors.grey[400]),),),) : Container(
child: Stack(children: <Widget>[
GoogleMap(
markers: _markers,
mapType: _currentMapType,
initialCameraPosition: CameraPosition(
target: _initialPosition,
zoom: 14.4746,
),
onMapCreated: _onMapCreated,
zoomGesturesEnabled: true,
onCameraMove: _onCameraMove,
myLocationEnabled: true,
compassEnabled: true,
myLocationButtonEnabled: false,
),
Align(
alignment: Alignment.topRight,
child: Container(
margin: EdgeInsets.fromLTRB(0.0, 50.0, 0.0, 0.0),
child: Column(
children: <Widget>[
mapButton(_onAddMarkerButtonPressed,
Icon(
Icons.add_location
), Colors.blue),
mapButton(
_onMapTypeButtonPressed,
Icon(
IconData(0xf473,
fontFamily: CupertinoIcons.iconFont,
fontPackage: CupertinoIcons.iconFontPackage),
),
Colors.green),
],
)),
)
]),
),
);
}
}
You seem to be missing setState in your initState.
It should look like this:
#override
void initState(){
super.initState();
Geolocator().getCurrentPosition().then((currloc){
setState((){
currentLocation = currloc;
});
});
}
Use GeoLocator package with google_maps_flutter
Sample Code:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
class MapScreen extends StatefulWidget {
#override
State<MapScreen> createState() => MapScreenState();
}
class MapScreenState extends State<MapScreen> {
LatLng initPosition = LatLng(0, 0); //initial Position cannot assign null values
LatLng currentLatLng= LatLng(0.0, 0.0); //initial currentPosition values cannot assign null values
LocationPermission permission = LocationPermission.denied; //initial permission status
Completer<GoogleMapController> _controller = Completer();
#override
void initState() {
super.initState();
getCurrentLocation();
checkPermission();
}
//checkPersion before initialize the map
void checkPermission() async{
permission = await Geolocator.checkPermission();
}
// get current location
void getCurrentLocation() async{
await Geolocator.getCurrentPosition().then((currLocation) {
setState(() {
currentLatLng =
new LatLng(currLocation.latitude, currLocation.longitude);
});
});
}
//call this onPress floating action button
void _currentLocation() async {
final GoogleMapController controller = await _controller.future;
getCurrentLocation();
controller.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(
bearing: 0,
target: currentLatLng,
zoom: 18.0,
),
));
}
//Check permission status and currentPosition before render the map
bool checkReady(LatLng? x, LocationPermission? y) {
if (x == initPosition || y == LocationPermission.denied || y == LocationPermission.deniedForever) {
return true;
} else {
return false;
}
}
#override
Widget build(BuildContext context) {
print(permission);
print("Current Location --------> " +
currentLatLng.latitude.toString() +
" " +
currentLatLng.longitude.toString());
return MaterialApp(
//remove debug banner on top right corner
debugShowCheckedModeBanner: false,
home: new Scaffold(
//ternary operator use for conditional rendering
body: checkReady(currentLatLng, permission)
? Center(child: CircularProgressIndicator())
//Stack : place floating action button on top of the map
: Stack(children: [
GoogleMap(
myLocationEnabled: true,
myLocationButtonEnabled: false,
zoomControlsEnabled: false,
mapType: MapType.normal,
initialCameraPosition: CameraPosition(target: currentLatLng),
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
//Positioned : use to place button bottom right corner
Positioned(
bottom: 0,
right: 0,
child: Container(
margin: EdgeInsets.all(15),
child: FloatingActionButton(
onPressed: _currentLocation,
child: Icon(Icons.location_on)),
),
),
]),
),
);
}
}
The problem is how to infuse text overlap on the custom google map marker with text which represents the vehicle registration number.
I have tried to use this method to have the text overlay on the icon
builder: (context) =>()
But is not recognized at all.
class MapsDemo extends StatefulWidget {
#override
State createState() => MapsDemoState();
}
class MapsDemoState extends State<MapsDemo> {
GoogleMapController mapController;
//Map<PermissionGroup, PermissionStatus> permissions = await PermissionHandler().requestPermissions([PermissionGroup.contacts]);import 'package:permission_handler/permission_handler.dart';
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: GoogleMap(
onMapCreated: (GoogleMapController controller) {
mapController = controller;
},
),
),
],
),
floatingActionButton: FloatingActionButton(onPressed: () {
double mq1 = MediaQuery.of(context).devicePixelRatio;
String icon = "images/car.png";
if (mq1>1.5 && mq1<2.5) {icon = "images/car2.png";}
else if(mq1 >= 2.5){icon = "images/car3.png";}
print("Mq 1"+mq1.toStringAsFixed(5));
String iconPath="lib/assets/move#3x.png";
mapController.addMarker(
MarkerOptions(
position: LatLng(37.4219999, -122.0862462),
infoWindowText: InfoWindowText("TEST","TEST"),
icon: BitmapDescriptor.fromAsset(iconPath),
consumeTapEvents: true,
/*builder: (context) =>(
)*/
//icon:BitmapDescriptor.fromAsset(assetName)
),
);
mapController.addMarker(
MarkerOptions(
position: LatLng(38.4219999, -122.0862462),
infoWindowText: InfoWindowText("tt","adfaf"),
icon: BitmapDescriptor.fromAsset("lib/assets/logo.png"),
anchor: Offset(100,160),
//icon:BitmapDescriptor.fromAsset(assetName)
),
);
mapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: LatLng(37.4219999, -122.0862462),
zoom: 15.0,
),
),
);
})
);
}
}
What I have shown is the icon appear correctly if you notice the white space on the right of the icon is where I want the registration number to appear.
try this :
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class MapsDemo extends StatefulWidget {
#override
State createState() => MapsDemoState();
}
class MapsDemoState extends State<MapsDemo> {
final Set<Marker> _markers = {};
void _onAddMarkerButtonPressed() {
print('in _onAddMarkerButtonPressed()');
setState(() {
_markers.add(Marker(
// This marker id can be anything that uniquely identifies each marker.
markerId: MarkerId("111"),
position: LatLng(30.666, 76.8127),
infoWindow: InfoWindow(
title: "bingo! This works",
),
icon: BitmapDescriptor.defaultMarker,
));
});
print('setState() done');
}
GoogleMapController mapController;
//Map<PermissionGroup, PermissionStatus> permissions = await PermissionHandler().requestPermissions([PermissionGroup.contacts]);import 'package:permission_handler/permission_handler.dart';
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: GoogleMap(
markers: _markers,
onMapCreated: (GoogleMapController controller) {
mapController = controller;
},
initialCameraPosition:
CameraPosition(target: LatLng(30.666, 76.8127), zoom: 15),
),
),
],
),
floatingActionButton: FloatingActionButton(onPressed: () {
print('in fab()');
double mq1 = MediaQuery.of(context).devicePixelRatio;
_onAddMarkerButtonPressed();
mapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: LatLng(30.666, 76.8127),
zoom: 15.0,
),
),
);
}));
}
}
I kludged/solved this by creating a function which returned a , whose returned and resolved value I then passed in as the icon when initializing a Marker:
Sorry to say that I don't remember why I padded the method with the magic 40 and 20 constants. Probably calculated by visual test with what I was rendering at the time.
Future<BitmapDescriptor> createCustomMarkerBitmap(/* your args here */) async {
PictureRecorder recorder = new PictureRecorder();
Canvas c = new Canvas(recorder);
/* Do your painting of the custom icon here, including drawing text, shapes, etc. */
Picture p = recorder.endRecording();
ByteData pngBytes = await (await p.toImage(
tp.width.toInt() + 40, tp.height.toInt() + 20))
.toByteData(format: ImageByteFormat.png);
Uint8List data = Uint8List.view(pngBytes.buffer);
return BitmapDescriptor.fromBytes(data);
}
Then when creating the marker, you can pass in the BitmapDescriptor as the icon, like so:
createCustomMarkerBitmap(...).then((BitmapDescriptor bitmapDescriptor) {
_markers.add(new Marker(
/* in addition to your other properties: */
icon: bitmapDescriptor,
));
});
or:
BitmapDescriptor bitmapDescriptor = await createCustomMarkerBitmap(...);
Marker marker = Marker(
/* in addition to your other properties: */
icon: bitmapDescriptor
);
Let me know if that helps. Gl!
I have found this answer for github issue
I found myself on this exact stackoverflow page multiple times this year. So, I decided to go and make my first Flutter Package and created this. If your objective is to add a simple and clear text to map marker, this would do it.
https://pub.dev/packages/label_marker
Usage
markers.addLabelMarker(LabelMarker(
label: "TextToShow",
markerId: MarkerId("idString"),
position: LatLng(10.0, 11.0),
backgroundColor: Colors.green,
)).then((value) {
setState(() {});
},
);
I'm just playing with new Google Map package of Flutter.
I want to change MapType of the map like, hybrid, satellite, none and etc by using of PopupMenuButton. Below are my code.
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class MapPage extends StatefulWidget {
#override
_MapPageState createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
GoogleMapController mapController;
List arrMapTyep = [
{'title': 'none', 'value': MapType.none},
{'title': 'hybrid', 'value': MapType.hybrid},
{'title': 'normal', 'value': MapType.normal},
{'title': 'satellite', 'value': MapType.satellite},
{'title': 'terrain', 'value': MapType.terrain}
];
MapType currentMapType = MapType.normal;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Google Map"),
actions: <Widget>[
PopupMenuButton(
icon: Icon(Icons.more_vert),
initialValue: currentMapType,
onSelected: (value) {
setState(() {
currentMapType = value;
});
},
itemBuilder: (BuildContext context) => _setupAllMapType()
)
],
),
body: Container(
child: GoogleMap(
onMapCreated: _onMapCreated,
options: GoogleMapOptions(
mapType: currentMapType,
compassEnabled: true,
myLocationEnabled: true,
cameraPosition: CameraPosition(
target: LatLng(37.785834, -122.406417),
zoom: 16,
)
),
),
),
);
}
void _onMapCreated(GoogleMapController controller) {
setState(() {
mapController = controller;
});
}
List<PopupMenuItem> _setupAllMapType() {
List<PopupMenuItem> temArr = List();
for (var i = 0; i < arrMapTyep.length; i++) {
temArr.add(
PopupMenuItem(
value: arrMapTyep[i]['value'],
child: Text(arrMapTyep[i]['title']),
),
);
}
return temArr;
}
}
I called setState but can work it.
I am not sure if it is too late to answer this, but in case someone like me stumbles upon this question;
Real time change in MapType, can be achieved using a setState() call upon currentMapType variable. I have implemented this in my application and it works smooth like butter!
Hope it helps. Happy Flutter'ing!
Quick reference (to change Normal map type to Satellite map type):
RaisedButton(
child: Text("Satellite"),
onPressed: () {
setState(() {
currentMapType = MapType.satellite;
});
},
)