osm_flutter
osm_flutter copied to clipboard
How to override default inforWindow of Marker
Hello I want to override default widget of Marker's info windows
How i can do that, i have search but don't see any information about it.
sorry for late reply for now , it's not possible due to some limitation we will try to provide this feature in future if you want to show popup on click try to use bottom sheet better to that case
@liodali @eddydn
Well there is a way to show the marker with what ever info or style you need for example check this video,
So, the basic idea is to put all your markers in a list and use onGeoPointClicked
to find the markers closest to the tap of your fingers and add a info window or anything you please on top of this .It will work on any platform as its just a simple logic.
https://user-images.githubusercontent.com/11044978/231046894-aa2f7269-8d8e-499f-a65f-a5dd3d84eceb.mp4
here check the sample code and it is upto you how you optimize it or add logic when to remove the info window, this should get you started until @liodali comes up with a better solution. I personally prefer doing it this way, my implementation is a little different as i have around 30k markers, and they are too small so i had to come up with this in other projects. You could use quadTree to better sort your list and optimize it further.
import 'package:flutter/material.dart';
import 'package:flutter_osm_plugin/flutter_osm_plugin.dart';
import 'package:latlong2/latlong.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late MapController osmController;
List<GeoPoint> point = [
GeoPoint(latitude: 27.41, longitude: 85.229444),
GeoPoint(latitude: 27.301667, longitude: 85.180278),
];
@override
void initState() {
super.initState();
osmController = MapController(
initMapWithUserPosition: true,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
child: Container(
height: double.infinity,
child: OSMFlutter(
onMapIsReady: (p0) async {
await osmController.addMarker(point[0],
markerIcon: const MarkerIcon(
icon: Icon(
Icons.pin_drop_outlined,
color: Colors.green,
size: 50,
)));
await osmController.addMarker(point[1],
markerIcon: const MarkerIcon(
icon: Icon(
Icons.pin_drop_outlined,
color: Colors.red,
size: 50,
)));
},
onGeoPointClicked: (p0) async {
GeoPoint? closestPoint;
double minDistance = double.infinity;
for (final marker in point) {
double distanceEnMetres = await distance2point(
GeoPoint(
longitude: p0.longitude,
latitude: p0.latitude,
),
marker,
);
if (distanceEnMetres < minDistance) {
minDistance = distanceEnMetres;
closestPoint = marker;
}
}
if (closestPoint != null) {
await osmController.addMarker(
closestPoint,
markerIcon: MarkerIcon(
iconWidget: Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 50),
child: Container(
color: Colors.blue,
height: 100,
width: 300,
child: const Center(
child: Text(
'Hello World',
style: TextStyle(color: Colors.white, fontSize: 15),
)),
),
),
),
);
}
},
//markerOption: ,
key: const PageStorageKey('myMap'),
controller: osmController,
trackMyPosition: false,
initZoom: 12,
minZoomLevel: 8,
maxZoomLevel: 14,
stepZoom: 1.0,
userLocationMarker: UserLocationMaker(
personMarker: const MarkerIcon(
icon: Icon(
Icons.location_history_rounded,
color: Colors.red,
size: 48,
),
),
directionArrowMarker: const MarkerIcon(
icon: Icon(
Icons.double_arrow,
size: 48,
),
),
),
),
),
),
],
));
}
}
@jesussmile I will be honest with you, your idea not bad but not efficient, because the popups are not interactive I will work on solution soon