create maker with InfoWindow flutter map - flutter

along with greeting you, I wanted to ask you if someone has been able to show an InfoWindow in the flutter map maker, or create a container that is floating so that it appears next to the maker, in google map if possible.
new Marker
(
width: 45.0,
height: 45.0,
point: new LatLng(-25.963678, -51.240657),
builder: (ctx) =>
new Container //here infoWindow or Float Container
(
//child: new FlutterLogo(),
child: IconButton
(
icon: Icon(Icons.location_on),
color: Colors.blue,
iconSize: 45.0,
tooltip: "prueba",
onPressed: ()
{
print("test press");
},
)
),
),
Thank you very much for the help as always.

You cannot set a widget as the marker info-window in any of the flutter map plugins. You can only set the title and text of the info-window in the google maps plugins.
You could turn the map info-window off, center the map on the marker if the user clicks on it, and add some code to show a custom dialog at the approximate center of the screen. You would have to use the flutter Stack widget.
Stack(
children:[
Map(
markers: [Marker(/*no info-window*/, onTap: (){
setState((){ _opacity = 1; });
})],
onMapMove: (){
setState((){ _opacity = 0; });
}
),
Opacity(
opacity: _opacity,
child: /*custom info-window*/,
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
),

Use custom_info_window package as follows:
Step 1: Initialise CustomInfoWindowController.
CustomInfoWindowController _customInfoWindowController = CustomInfoWindowController();
Step 2: Call CustomInfoWindowController's addInfoWindow from marker's onTap function.
Marker(
markerId: MarkerId("marker_id"),
position: _latLng,
onTap: () {
_customInfoWindowController.addInfoWindow(
<YOUR CUSTOM WIDGET>,
_latLng,
);
},
)
Step 3: Use GoogleMap Widget with Stack.
Stack(
children: <Widget>[
GoogleMap(
onTap: (position) {
_customInfoWindowController.hideInfoWindow();
},
onCameraMove: (position) {
_customInfoWindowController.onCameraMove();
},
onMapCreated: (GoogleMapController controller) async {
_customInfoWindowController.googleMapController = controller;
},
markers: _markers,
initialCameraPosition: CameraPosition(
target: _latLng,
zoom: _zoom,
),
),
CustomInfoWindow(
controller: _customInfoWindowController,
height: 75,
width: 150,
offset: 50,
),
],
)
Call _customInfoWindowController.hideInfoWindow(); inside GoogleMap's onTap to hide CustomInfoWindow when clicking on map but not on the marker.
Call _customInfoWindowController.onCameraMove(); to maintain CustomInfoWindow's position relative to marker. [IMPORTANT]
Assign _customInfoWindowController.googleMapController = controller; inside onMapCreated. [IMPORTANT]
Add CustomInfoWindow as next child to float this on top GoogleMap.

Related

Marker positions got updated but the marker did not get redrawn on google map when using geolocator pub dev

I am trying to make a moving google map marker according to the user location, I use the geolocator listen function from the geolocator pub dev. The position of the markers got updated however the marker did not show up on the google map at all I tried using setState(){} to refresh the map, however nothing change.
Here's the function that I use
void listenToLocation()
{
Position? userposition;
final LocationSettings _locationSettings = LocationSettings(accuracy: LocationAccuracy.high,distanceFilter: 100);
userStreamlocation = Geolocator.getPositionStream(locationSettings: _locationSettings).listen(
(userposition) {
print(userposition == null ? 'Unknown' : '${userposition.latitude.toString()}, ${userposition.longitude.toString()}');
useablepos=LatLng(userposition.latitude, userposition.latitude);
_Navmarkers.remove(UserMarker);
print('USABLE POSITION:' + useablepos.toString());
UserMarker = Marker(
markerId: MarkerId('User'),
icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueCyan),
position: useablepos,
draggable: true,);
_Navmarkers.add(UserMarker);
setState(){};
print('User Location :' + UserMarker.position.toString());
});
}
I am able to remove the user marker and replace it with a new marker that have the new position however the marker did not show up on the googlemap
Here's the image to show that the LatLng keep getting updated,
Edit: UI Screenshot, there is only a single button that function to start the listen function
Update: I tried several thing and the only thing I found out is that the listen run outside the map state, I still have no idea what to do
I am able to fix this after finding out that the marker didn't got updated because it is in a different state than the main widget, I fix it trough the use of the statebuilder widget. Apparently without statefulbuilder, the setState refresh the whole app but not what the function do. here's the code snip
StatefulBuilder(
builder: (context, setMapState) {
setMapState(
() {},
);
void _whenMapCreated(GoogleMapController controller) async {
//debugPrint('>>>>>>>>> onMapCreated');
mapController = controller;
_Navmarkers.clear();
_navPolylines.clear();
var direction =
await LocationService().getDirectionNoWP(userOrigin, userGoal);
_setPolylines(direction['polyline_decoded']);
setMapState(
() {},
);
}
return Column(children: [
Expanded(
child: GoogleMap(
mapType: MapType.normal,
initialCameraPosition:
CameraPosition(target: _kGooglePlex, zoom: 11),
markers: _Navmarkers,
polylines: _navPolylines,
onMapCreated: _whenMapCreated,
)),
Row(
children: [
ButtonBar(
children: [
IconButton(
onPressed: () {
Position? userposition;
const LocationSettings _locationSettings =
LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 100,
);
userStreamlocation = Geolocator.getPositionStream(
locationSettings: _locationSettings)
.listen((userposition) {
_Navmarkers.clear();
_Navmarkers.add(Marker(
markerId: MarkerId('User'),
position: LatLng(userposition.latitude,
userposition.longitude),
icon: BitmapDescriptor.defaultMarkerWithHue(
BitmapDescriptor.hueRose)));
setMapState(() {
});
});
},
icon: Icon(Icons.navigation)),
IconButton(
onPressed: () {
setMapState(
() {
},
);
},
icon: Icon(Icons.refresh)),
IconButton(
onPressed: () {
dispose();
},
icon: Icon(Icons.stop))
],
)
],
)
]);
},
),

How to add custom onTap in marker flutter map?

I have a map in flutter where I have to commute the user to a specific point using directions. The red marker on the map when on pressed automatically shows directions on the bottom right but I want to show an arrow head to the user to click the directions on the bottom right because user may not notice it by themselves: https://imgur.com/a/lv9Xq9T
This is the code snippet :
void getLocation() async {
var location = await currentLocation.getLocation();
currentLocation.onLocationChanged.listen((LocationData loc) {
mapcontroller.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
target: LatLng(loc.latitude ?? 0.0, loc.longitude ?? 0.0), zoom: 5)));
setState(() {
clat = loc.latitude;
clng = loc.longitude;
_markers.addAll({
Marker(
markerId: const MarkerId('Shopkeeper Position'),
icon: BitmapDescriptor.defaultMarker,
// position: LatLng(20.7708612, 73.7235274))
position: LatLng(
widget.latitude,
widget.longitude,
),
onTap: () {
print("");
print("");
print("Marker pressed");
print("");
print("");
Container(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Get Directions",
style: GoogleFonts.roboto(
fontSize: 40,
fontWeight: FontWeight.w800,
color: Colors.blue,
),
),
Image.asset(
'assets/arrowHead.gif',
width: 200,
height: 200,
),
],
),
);
},
)
});
});
getPolypoints();
});
}
All i get when I tap on the marker are the print statements. I would want to display the row widget as well. How can i do this ?
You need to move your directions container and show/hide depending on the onTap.
Something like this:
isTapped ?? directionsContainer : Container() // empty container if isTapped is false
Update your onTap: to update state with a boolean:
setState(() {
isTapped = !isTapped;
})

Flutter's Google Maps plugin onTap not working

I'm creating simple app, and I need that when the map is tapped a marker should be added. I'm using the onTap property of the google_maps_flutter plugin:
var markers = Set<Marker>();
...
body: Stack(
children: [
Positioned.fill(
child: GoogleMap(
onTap: (LatLng point) {
print(point.longitude.toString());
final snackBar = SnackBar(
content: Text(point.longitude.toString()),
action: SnackBarAction(
label: 'Undo',
onPressed: () {
// Blah.
},
),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
setState(() {
markers.add(Marker(
markerId: MarkerId(point.toString()),
position: point,
infoWindow: InfoWindow(
title: 'I am a marker in ${point}',
),
icon: BitmapDescriptor.defaultMarkerWithHue(
BitmapDescriptor.hueMagenta),
anchor: Offset(100, 160),
));
});
},
//--
myLocationEnabled: true,
zoomControlsEnabled: false,
markers: markers,
initialCameraPosition: CameraPosition(
target: currentLocation,
),
onMapCreated: (GoogleMapController controller) {
_mapController.complete(controller);
},
),
),
...
I added a print and a snackbar just to make sure I was getting the location information, and works just fine. I don't get any errors anywhere. I also added the map directly into the body (no Stack), and still doesn't do anything. I'm not sure what's happening. I can add more portions of then code if needed.

How to fix Flutter google map picker problem?

I'm using google map picker. But appearing problem when I select place
RangeError (RangeError (index): Invalid value: Valid value range is empty: 0)
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () async {
LocationResult result = await showLocationPicker(
context,
"blablablagooglekey",
initialCenter: LatLng(41.2995, 69.2401),
myLocationButtonEnabled: true,
layersButtonEnabled: true,
desiredAccuracy: LocationAccuracy.best,
);
print("result = $result");
setState(() => _pickedLocation = result);
},
child: Text('Pick location'),
),
Text(_pickedLocation.toString() ?? 'Test'),
],
),
);
How can I fix this?
I need select place for meeting buttun.
If you trying to achieve map picker, try this package:
https://pub.dev/packages/map_picker.
MapPicker(
// pass icon widget
iconWidget: SvgPicture.asset(
"assets/location_icon.svg",
height: 60,
),
//add map picker controller
mapPickerController: mapPickerController,
child: GoogleMap(
myLocationEnabled: true,
zoomControlsEnabled: false,
// hide location button
myLocationButtonEnabled: false,
mapType: MapType.normal,
// camera position
initialCameraPosition: cameraPosition,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
onCameraMoveStarted: () {
// notify map is moving
mapPickerController.mapMoving!();
textController.text = "checking ...";
},
onCameraMove: (cameraPosition) {
this.cameraPosition = cameraPosition;
},
onCameraIdle: () async {
// notify map stopped moving
mapPickerController.mapFinishedMoving!();
//get address name from camera position
List<Placemark> placemarks = await placemarkFromCoordinates(
cameraPosition.target.latitude,
cameraPosition.target.longitude,
);
// update the ui with the address
textController.text =
'${placemarks.first.name}, ${placemarks.first.administrativeArea}, ${placemarks.first.country}';
},
),
),

Getting the Position Stream from Geolocator into StreamBuilder Flutter

I'm just starting with Flutter and very new to State/Stream/BloC concepts. I'm trying to update a FlutterMap center based on the coordinates from a Geolocator()'s Position stream. At the moment I'm just calling setState() updating a variable with the new value, but next I'll be trying using the Bloc pattern instead..
Now, as well as I set the center on the coordinates of the Position coming from the stream I also set a Marker on the same coordinates. I was expecting to see a Steady marker in the center of the screen and a moving map underneath but is the opposite.. the Map is steady and the Icon is moving.. Can you see where I got it wrong?
Also, for the stream: property of the StreamBuilder how would I get to pass the stream from Geolocator() as an event?
Many thanks for your time and help.
This is the Stream:
StreamSubscription positionStream = _geolocator
.getPositionStream(locationOptions)
.listen((Position position) {
setState(() {
_position = position;
});
print(
_position.latitude.toString() + ',' + _position.longitude.toString()); // ok
});
And this is the Map and the Marker:
Container(
height: 670,
width: 370,
child: FlutterMap(
options: MapOptions(
center: LatLng(_position.latitude, _position.longitude),
minZoom: 16.0,
maxZoom: 19.0,
),
layers: [
TileLayerOptions(
// urlTemplate:
// 'https://api.openrouteservice.org/mapsurfer/{z}/{x}/{y}.png?api_key=omitted',
urlTemplate:
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
subdomains: ['a', 'b', 'c'],
keepBuffer: 20),
new MarkerLayerOptions(
markers: [
new Marker(
point: new LatLng(
_position.latitude, _position.longitude),
height: 200,
width: 200,
builder: (context) => IconButton(
icon: Icon(Icons.location_on),
color: Colors.red,
iconSize: 60,
onPressed: () {
print('icon tapped');
},
)),
],
),
],
),
),
Found the problem. I didn't assign any MapController().
So I created one and assign it to the FlutterMap. Inside the setState() I added _controller.move(LatLng(_position.latitude, _position.longitude), 16.0); and now the behaviour is the expected one. Steady Icon in the center of the screen and a moving map underneath.
Hope this will help others.
But still I will try to achieve the same with a BLoC pattern.
Cheers