This guide helps you migrate to the new Cupertino-based architecture with enhanced customization capabilities. The refactor focused on:
- 🍎 Native Cupertino UI components
- 🌗 Built-in theme support (light/dark)
- 🧩 Decoupled service architecture
- 🚀 Performance optimizations
- 🗺️ Advanced map customization
lib/
├── src/
│ ├── autocomplete_service.dart // Autocomplete business logic
│ ├── autocomplete_view.dart // Cupertino-style search UI
│ ├── geocoding_service.dart // Reverse geocoding logic
│ ├── map_location_picker.dart // Main picker widget
│ ├── debouncer.dart // Debounce utility
│ └── logger.dart // Logging utility
└── map_location_picker.dart // Main export
Changed from Material to Cupertino:
// Old (Material)
PlacesAutocomplete(
decoration: InputDecoration(...),
)
// New (Cupertino)
PlacesAutocomplete(
// Uses CupertinoTypeAheadField internally
)Migration Strategy:
- Replace Material widgets with Cupertino equivalents
- Use new Cupertino-style configuration options
- Remove manual theme handling - it's now automatic
New Configuration Approach:
MapLocationPicker(
config: MapPickerConfig(
apiKey: '...',
initialPosition: LatLng(...),
// Map-specific parameters
bottomCardBuilder: (ctx, result, address, isLoading, onNext) {
return CupertinoActionSheet(...);
}
),
searchConfig: PlacesAutocompleteConfig(
apiKey: '...',
searchHintText: 'Search locations...',
// Autocomplete parameters
),
)Decoupled Services:
// Geocoding Service
final geoCodingService = GeoCodingService(apiKey: "...");
final (result, allResults) = await geoCodingService.reverseGeocode(position);
// Autocomplete Service
final autoCompleteService = AutoCompleteService();
final predictions = await autoCompleteService.search(query: "Paris");| Old Parameter | New Location | Notes |
|---|---|---|
apiKey |
MapPickerConfig.apiKey |
|
currentLatLng |
MapPickerConfig.initialPosition |
|
searchHintText |
PlacesAutocompleteConfig.searchHintText |
|
language |
PlacesAutocompleteConfig.suggestionsLanguage |
|
onMapCreated |
MapPickerConfig.onMapCreated |
|
onMapTypeChanged |
MapPickerConfig.onMapTypeChanged |
|
additionalMarkers |
MapPickerConfig.additionalMarkers |
|
customMarkerIcons |
MapPickerConfig.customMarkerIcons |
|
bottomCardBuilder |
MapPickerConfig.bottomCardBuilder |
Signature changed |
defaultAddressText |
PlacesAutocompleteConfig.defaultAddressText |
|
mapStyle |
MapPickerConfig.mapStyle |
Old:
bottomCardBuilder: (ctx, result, address, isLoading) {...}New:
bottomCardBuilder: (ctx, result, address, isLoading, onNext) {
return CupertinoActionSheet(
actions: [
CupertinoActionSheetAction(
onPressed: onNext, // New callback
child: Text(address),
),
],
);
}New Approach:
MapPickerConfig(
mapTypeButton: CupertinoButton(...), // Fully customizable
locationButton: CustomLocationButton(),
)Image.network(
googleStaticMapWithMarker(
lat, lng, zoom,
apiKey: "YOUR_KEY"
),
)Automatic light/dark theme adaptation:
final _themeMode = ValueNotifier<ThemeMode>(ThemeMode.dark);
MapLocationPicker(
config: MapPickerConfig(), // Automatically adapts to theme
)void _createMarkerIcon() async {
_customMarkerIcon = await BitmapDescriptor.asset(
const ImageConfiguration(size: Size(48, 48)),
'assets/marker.webp',
);
}
MapPickerConfig(
mainMarkerIcon: _customMarkerIcon,
)MapPickerConfig(
bottomCardBuilder: (ctx, result, address, isLoading, onNext) {
return CupertinoActionSheet(
title: Text("Confirm Location"),
actions: [
CupertinoActionSheetAction(
onPressed: onNext,
isDefaultAction: true,
child: Text(address),
),
],
);
},
)dependencies:
map_location_picker: ^2.0.0Old:
MapLocationPicker(
apiKey: "...",
currentLatLng: LatLng(...),
// 100+ parameters
)New:
MapLocationPicker(
config: MapPickerConfig(
apiKey: "...",
initialPosition: LatLng(...),
// Map config
),
searchConfig: PlacesAutocompleteConfig(
apiKey: "...",
// Search config
),
)Bottom Card:
// Old
bottomCardBuilder: (ctx, result, address, isLoading) {...}
// New
config: MapPickerConfig(
bottomCardBuilder: (ctx, result, address, isLoading, onNext) {
return CupertinoActionSheet(
actions: [
CupertinoActionSheetAction(
onPressed: onNext,
child: Text(address),
),
],
);
}
)For advanced use cases:
MapLocationPicker(
geoCodingService: MyCustomGeoCodingService(),
// Other services...
)Remove manual theme handling:
- Theme(
- data: ThemeData.dark(),
- child: MapLocationPicker(...)
- )
// The picker now automatically adapts to app themeProblem: UI elements look different Solution: The UI has been updated to Cupertino design. Use new customization options:
PlacesAutocompleteConfig(
decorationBuilder: (context, child) {
return CupertinoBoxDecoration(child: child);
}
)Problem: Bottom card not working
Solution: Signature changed - now includes onNext callback:
bottomCardBuilder: (ctx, result, address, isLoading, onNext) {
return Button(onPressed: onNext, child: Text("Select"));
}Problem: Markers not showing Solution: Use new marker configuration:
MapPickerConfig(
mainMarkerIcon: BitmapDescriptor.defaultMarker,
additionalMarkers: {
"custom": LatLng(37.422, -122.084),
},
customMarkerIcons: {
"custom": BitmapDescriptor.defaultMarkerWithHue(120),
},
)Problem: Search not working Solution: Ensure you're using the new config:
PlacesAutocomplete(
config: PlacesAutocompleteConfig(
apiKey: "YOUR_KEY",
minCharsForSuggestions: 2,
),
// Not in MapPickerConfig
)- Native Experience: Cupertino design for iOS and Material for Android
- Theme Support: Automatic light/dark mode adaptation
- Better Performance: Optimized rebuilds and memoization
- Enhanced Customization: More control over UI components
- Simplified Maintenance: Decoupled architecture
- New Features: Static map previews, better markers, etc.
For additional help, refer to the updated example app or file an issue on GitHub.