kryonex_address_picker 0.0.9
kryonex_address_picker: ^0.0.9 copied to clipboard
An opinionated, search-first address picker for Flutter with map confirmation, selectable OpenStreetMap or Google Maps rendering, and structured address output.
◆ kryonex_address_picker #
A search-first address picker for Flutter. Geocoding · map confirmation · structured output — in one call.
showAddressPicker(context) → a fully-typed address.
— built by Kryonex Labs —
⟶ Demo #
Search · confirm on map · capture details — all in one flow.
Screenshots #
Part 1 — Finding a location
| 1. Entry point | 2. Search | 3. Map confirm |
![]() |
![]() |
![]() |
Host app launches the picker by calling
showAddressPicker(context).See example/lib/main.dart · HomePage
|
Debounced Photon autocomplete, Use current location (opens map confirm at the resolved location), and
Pick on Map entry points. Recent picks appear here too.See lib/src/screens/search_screen.dart
|
Tap-to-drop pin on an OSM map with reverse geocoding, a "Locate Me" FAB,
and the live address card. See lib/src/screens/map_confirm_screen.dart
|
Part 2 — Capturing details & result
| 4. Detail sheet | 5. Result |
![]() |
![]() |
|
Frosted-glass bottom sheet collecting custom fields — Apt, Floor, a
custom Gate code with quick-fill chips, Postal Code, and Delivery Notes. Configured via AddressFieldSpec — see the Configurable detail fields section
|
The returned SelectedAddress rendered back in the host app —
structured address fields plus the captured detail values.See example/lib/main.dart · result rendering
|
⟶ Why #
Address entry is usually a mess of free-text fields and bad data. This is the opposite: type, confirm on a map, done. You get back clean, structured, geocoded results.
Powered by Komoot Photon (OpenStreetMap data, no API key),
flutter_map or
google_maps_flutter, and
ForUI components.
⟶ Features #
◆ Search-first debounced Photon autocomplete
◆ Map confirmation selectable OpenStreetMap or Google Maps renderer
◆ Structured output street · city · state · postal · country · latLng
◆ Address details apt · floor · delivery notes
◆ Recent addresses locally persisted picks
◆ Current location opens map confirm after resolving coordinates
◆ Map styling light / dark / auto tile mode
◆ Custom pin marker `pinBuilder` support for any marker widget
◆ Confirm button styling override via `confirmButtonStyle`
◆ Attribution control declarative OSM attribution and alignment
◆ ForUI native polished, accessible UI out of the box
◆ Zero-config theming auto-bridges to your Material theme
⟶ Install #
dependencies:
kryonex_address_picker: ^0.1.0
⟶ Quick Start #
import 'package:kryonex_address_picker/kryonex_address_picker.dart';
final result = await showAddressPicker(context);
if (result != null) {
result.address.displayName; // "123 Main St, Springfield, IL 62701, USA"
result.address.street; // "Main Street"
result.address.city; // "Springfield"
result.address.latLng; // LatLng(39.7817, -89.6501)
result.details?.apt; // "Apt 4B"
result.details?.deliveryNotes; // "Leave at the door"
}
With configuration:
final result = await showAddressPicker(
context,
config: AddressPickerConfig(
countryCodes: ['us', 'ca'],
maxRecentAddresses: 10,
searchHint: 'Where to?',
showDetailScreen: true,
detailFields: [
AddressFieldSpec.apt,
AddressFieldSpec.deliveryNotes,
],
),
);
Configurable detail fields #
The detail step is a frosted-glass bottom sheet presented over the confirmed
map. Its fields are fully composable via AddressFieldSpec: mix the built-in
presets with your own custom fields, with per-field icons, validation,
keyboard types, and quick-fill chips.
Built-in presets: AddressFieldSpec.apt, .floor, and .deliveryNotes (the
default set), plus .postalCode (opt-in — handy for international addresses).
config: AddressPickerConfig(
detailFields: [
AddressFieldSpec.apt, // built-in preset
AddressFieldSpec.floor, // built-in preset
AddressFieldSpec( // custom field
key: 'gate',
label: 'Gate code',
icon: Icons.pin_outlined,
keyboardType: TextInputType.number,
required: true,
quickFills: ['1234', '0000'],
),
AddressFieldSpec.deliveryNotes,
],
),
// Read values back by key:
result.details?['gate']; // "1234"
result.details?.apt; // built-in convenience getter, still works
Pre-filling fields from the confirmed address
Use prefillFrom to seed a field with an attribute captured during map
confirmation. The user can still edit the value before saving.
AddressFieldSpec(
key: 'city',
label: 'City',
icon: Icons.location_city_outlined,
prefillFrom: AddressAttribute.city, // seeds the field on sheet open
),
// The built-in postalCode preset pre-fills automatically:
AddressFieldSpec.postalCode,
AddressAttribute covers every field on StructuredAddress:
displayName, street, houseNumber, city, state, postalCode,
country, countryCode, latitude, longitude, primaryLine,
secondaryLine.
You can also use AddressAttributeReader.readAttribute(attribute) to extract any
attribute value as a string.
The sheet's appearance is configurable too — see detailSheetTitle,
detailSheetSubtitle, saveButtonLabel, sheetBlurSigma,
sheetCornerRadius, sheetAccentColor, showDragHandle, sheetDismissible,
and sheetEnableDrag in the table below.
Map customization #
The picker also supports map-specific customization via AddressPickerConfig.
Use the configuration fields below to:
- choose OpenStreetMap (default) or Google Maps with
mapProvider - toggle tile dark mode with
MapDarkMode.auto,MapDarkMode.light, orMapDarkMode.dark - render a custom map pin via
pinBuilder - override the confirm button style with
confirmButtonStyle - control OSM attribution via
AddressPickerAttribution.osmor a customAddressPickerAttribution - position attribution in the map corners with
MapAttributionAlignment.bottomLeftorMapAttributionAlignment.bottomRight
Choose Google Maps like this:
final result = await showAddressPicker(
context,
config: const AddressPickerConfig(
mapProvider: AddressPickerMapProvider.googleMaps,
),
);
The host application must enable the appropriate Maps SDK and configure its
API key for Android, iOS, or web. googleMapsApiKey remains the optional key
used by this package's Places and Geocoding REST services; it does not replace
the platform configuration required to render a Google map.
mapDarkMode, pinBuilder, and attributionStyle customize the OpenStreetMap
renderer. Google Maps supplies its native marker and manages its own styling
and attribution.
⟶ Configuration #
| Parameter | Type | Default | Description |
|---|---|---|---|
theme |
FThemeData? |
null |
Explicit ForUI theme (highest priority) |
materialTheme |
ThemeData? |
null |
Material theme to auto-bridge |
initialLocation |
LatLng? |
null |
Initial map center |
countryCodes |
List<String>? |
null |
ISO country-code filter for search (takes priority over localeAwareSearch) |
localeAwareSearch |
bool |
true |
Auto-restrict results to the device locale's country (ignored when countryCodes is set) |
maxRecentAddresses |
int |
5 |
Max recent addresses to store |
showDetailScreen |
bool |
true |
Show the detail sheet after map confirm |
detailFields |
List<AddressFieldSpec>? |
apt, floor, notes | Which detail fields to display, and in what order |
searchHint |
String? |
null |
Search bar placeholder (falls back to "Search for an address...") |
mapProvider |
AddressPickerMapProvider |
openStreetMap |
Confirmation map renderer: openStreetMap or googleMaps |
mapZoom |
double |
16.0 |
Default map zoom level |
mapDarkMode |
MapDarkMode |
auto |
Controls tile dark-mode emulation: auto, light, or dark |
pinBuilder |
WidgetBuilder? |
null |
Custom map pin widget builder; renders instead of the default MapPin |
confirmButtonStyle |
ButtonStyle? |
null |
Override the style of the Confirm Address button |
attributionStyle |
AddressPickerAttribution? |
AddressPickerAttribution.osm |
Configures OSM attribution text, URI, background, and alignment; set to null to hide it |
detailSheetTitle |
String |
"Add details" |
Title at the top of the detail sheet |
detailSheetSubtitle |
String? |
null |
Optional subtitle under the title |
saveButtonLabel |
String |
"Save address" |
Label for the sheet's save button |
sheetBlurSigma |
double |
18.0 |
Backdrop blur strength behind the sheet |
sheetCornerRadius |
double |
28.0 |
Sheet top corner radius |
sheetAccentColor |
Color? |
theme primary | Glow colour of the save button |
showDragHandle |
bool |
true |
Show the drag handle |
sheetDismissible |
bool |
true |
Tap-scrim to dismiss |
sheetEnableDrag |
bool |
true |
Drag-down to dismiss |
⟶ Output Model #
class SelectedAddress {
final StructuredAddress address;
final AddressDetails? details;
}
class StructuredAddress {
final String displayName; // Full address string
final LatLng latLng; // Geographic coordinates
final String? street; // "Main Street"
final String? houseNumber; // "123"
final String? city; // "Springfield"
final String? state; // "Illinois"
final String? postalCode; // "62701"
final String? country; // "United States"
final String? countryCode; // "us"
}
class AddressDetails {
final Map<String, String?> values; // keyed by AddressFieldSpec.key
String? operator [](String key); // values['gate']
String? get apt; // convenience: values['apt']
String? get floor; // convenience: values['floor']
String? get deliveryNotes; // convenience: values['deliveryNotes']
bool get isEmpty; // true when no field has a value
bool get isNotEmpty;
}
⟶ Theming #
The picker adapts to your app automatically, in priority order:
// 1 — Explicit ForUI theme (highest priority)
showAddressPicker(context, config: AddressPickerConfig(
theme: FThemes.zinc.dark,
));
// 2 — Material theme bridge
showAddressPicker(context, config: AddressPickerConfig(
materialTheme: ThemeData(colorSchemeSeed: Colors.blue),
));
// 3 — Auto-detect (zero config)
showAddressPicker(context);
⟶ Platform Setup #
Google Maps renderer #
When using AddressPickerMapProvider.googleMaps, follow the official
google_maps_flutter setup
for every target platform. Enable Maps SDK for Android, Maps SDK for iOS, or
Maps JavaScript API for web, then add a restricted API key to the host app.
The current plugin supports Android, iOS, and web; it does not provide native
desktop maps.
Location permissions (geolocator) #
The "Use current location" feature needs platform-specific permissions.
Android — android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
iOS — ios/Runner/Info.plist:
<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to find nearby addresses.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>We need your location to find nearby addresses.</string>
macOS — DebugProfile.entitlements and Release.entitlements:
<key>com.apple.security.personal-information.location</key>
<true/>
Web — no setup needed; uses the browser Geolocation API.
Internet permission (Android) #
Required for Photon API calls and map tiles — AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
Kryonex Labs · MIT License
Geocoding by Komoot Photon · OpenStreetMap data




