osm_location_picker 1.0.2
osm_location_picker: ^1.0.2 copied to clipboard
A self-contained Flutter location picker powered by OpenStreetMap. No API key required. Supports address search, GPS, and full theming.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:osm_location_picker/osm_location_picker.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Location Picker Example',
debugShowCheckedModeBanner: false,
locale: const Locale('en'),
supportedLocales: const [Locale('ar'), Locale('en')],
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
theme: ThemeData(
primaryColor: const Color(0xffEA3433),
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xffEA3433)),
useMaterial3: true,
),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
LocationModel? _selectedLocation;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Location Picker Demo'),
centerTitle: true,
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
),
body: Padding(
padding: const EdgeInsets.all(24.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_selectedLocation != null) ...[
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Theme.of(
context,
).colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(16),
),
child: Column(
children: [
const Icon(
Icons.my_location_rounded,
size: 40,
color: Color(0xffEA3433),
),
const SizedBox(height: 12),
Text(
'Address:',
style: Theme.of(context).textTheme.titleMedium
?.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: 4),
Text(
_selectedLocation!.address ?? 'No address returned',
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 15),
),
const SizedBox(height: 12),
const Divider(),
const SizedBox(height: 8),
Text(
'Coordinates:',
style: Theme.of(context).textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.bold,
),
),
Text(
'${_selectedLocation!.latLng?.latitude.toStringAsFixed(6)}, ${_selectedLocation!.latLng?.longitude.toStringAsFixed(6)}',
style: Theme.of(context).textTheme.bodyMedium,
),
],
),
),
] else ...[
const Icon(
Icons.location_off_rounded,
size: 80,
color: Colors.grey,
),
const SizedBox(height: 16),
const Text(
'No Location Selected',
style: TextStyle(
fontSize: 16,
color: Colors.grey,
fontWeight: FontWeight.bold,
),
),
],
const SizedBox(height: 40),
ElevatedButton.icon(
onPressed: () async {
final result = await Navigator.of(context)
.push<LocationModel>(
MaterialPageRoute(
builder: (context) => LocationPickerView(
initialLatLng: _selectedLocation?.latLng,
initialAddress: _selectedLocation?.address,
),
),
);
if (result != null) {
setState(() {
_selectedLocation = result;
});
}
},
icon: const Icon(Icons.map_rounded),
label: const Text('Open Location Picker'),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xffEA3433),
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(
horizontal: 32,
vertical: 16,
),
textStyle: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
),
],
),
),
),
);
}
}