Google Places Autocomplete
A powerful, UI-agnostic Flutter package for Google Places API integration. Get autocomplete predictions with distance from user, detailed place information, and full control over your UI.
✨ Features
- 🎨 UI-Agnostic - Bring your own UI, we handle the data
- 📍 Distance Support - Show distance from user to each prediction
- 🔐 Platform-Native API Keys - Read from AndroidManifest/Info.plist (no hardcoded keys!)
- 🌍 Cross-Platform - Android, iOS
- ⚡ Performance Optimized - Built-in debouncing
- 🔧 Highly Configurable - Filter by country, place type, language
🚀 Quick Start
1. Platform Setup
Android - Add to AndroidManifest.xml:
<application>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_API_KEY" />
</application>
iOS - Add to Info.plist:
<key>GOOGLE_PLACES_API_KEY</key>
<string>YOUR_API_KEY</string>
2. Install
dependencies:
google_places_autocomplete: ^1.0.0
3. Use
import 'package:google_places_autocomplete/google_places_autocomplete.dart';
final places = GooglePlacesAutocomplete(
// Optional - reads from platform config if not provided
// apiKey: 'YOUR_KEY',
// Optional - enables distance display in predictions
originLat: userLatitude,
originLng: userLongitude,
predictionsListener: (predictions) {
for (final p in predictions) {
print('${p.title} - ${p.distanceMeters}m away');
}
},
loadingListener: (isLoading) => print('Loading: $isLoading'),
);
await places.initialize(); // Important: await this!
places.getPredictions('coffee shop');
📖 API Reference
Constructor Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
predictionsListener |
Function(List<Prediction>) |
✅ | Callback for predictions |
loadingListener |
Function(bool) |
❌ | Loading state callback |
apiKey |
String? |
❌ | API key (uses platform config if null) |
originLat |
double? |
❌ | User latitude for distance calculation |
originLng |
double? |
❌ | User longitude for distance calculation |
debounceTime |
int |
❌ | Debounce in ms (default: 300, min: 200) |
countries |
List<String>? |
❌ | Country codes e.g. ['us', 'ca'] |
primaryTypes |
List<String>? |
❌ | Place types e.g. ['restaurant'] |
language |
String? |
❌ | Language code e.g. 'en' |
Methods
// Initialize (required, async)
await places.initialize();
// Get predictions
places.getPredictions('search query');
// Get place details
final details = await places.getPredictionDetail('place_id');
// Update user location (for distance)
places.setOrigin(latitude: 37.7749, longitude: -122.4194);
// Clear origin (disable distance)
places.clearOrigin();
Prediction Model
class Prediction {
final String? placeId; // Use with getPredictionDetail()
final String? title; // Main text
final String? description; // Secondary text
final int? distanceMeters; // Distance from origin (if set)
final List<String>? types; // Place types
}
PlaceDetails Model
class PlaceDetails {
final String? name;
final String? formattedAddress;
final Location? location; // .lat, .lng
final String? nationalPhoneNumber;
final String? internationalPhoneNumber;
final String? googleMapsUri;
final String? websiteUri;
// ... and more
}
💡 Examples
Display Distance Badge
ListTile(
title: Text(prediction.title ?? ''),
subtitle: Text(prediction.description ?? ''),
trailing: prediction.distanceMeters != null
? Text(_formatDistance(prediction.distanceMeters!))
: null,
);
String _formatDistance(int meters) {
if (meters >= 1000) {
return '${(meters / 1000).toStringAsFixed(1)} km';
}
return '$meters m';
}
Filter by Country
GooglePlacesAutocomplete(
countries: ['pk', 'ae'], // Pakistan & UAE only
predictionsListener: (p) => setState(() => predictions = p),
);
Get Coordinates from Selection
onTap: () async {
final details = await places.getPredictionDetail(prediction.placeId!);
final lat = details?.location?.lat;
final lng = details?.location?.lng;
// Use coordinates...
}
⚠️ Breaking Changes (v0.1.1)
| Change | Before | After |
|---|---|---|
| Listener names | predictionsListner |
predictionsListener |
loadingListner |
loadingListener |
|
| Initialize | initialize() (sync) |
await initialize() (async) |
| API key | Required | Optional (platform fallback) |
🔧 Troubleshooting
| Issue | Solution |
|---|---|
| No predictions | Ensure Places API is enabled in Google Cloud Console |
| No distance shown | Provide originLat and originLng |
| API key not found | Check platform manifest/plist configuration |
📄 License
MIT License - see LICENSE for details.