Add Dialog with Pageview to select new house, and then drop a pin where the house is, then zoom map to that area.
This commit is contained in:
88
lib/utilities/google_places_helper.dart
Normal file
88
lib/utilities/google_places_helper.dart
Normal file
@@ -0,0 +1,88 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_google_places_sdk/flutter_google_places_sdk.dart';
|
||||
import 'package:wheres_my_sign/common/functions.dart';
|
||||
|
||||
class GooglePlacesHelper {
|
||||
final FlutterGooglePlacesSdk _places;
|
||||
bool _isHandlingSelection = false;
|
||||
|
||||
GooglePlacesHelper(String apiKey) : _places = FlutterGooglePlacesSdk(apiKey);
|
||||
|
||||
void attachAddressListener({
|
||||
required TextEditingController controller,
|
||||
required FocusNode focusNode,
|
||||
required void Function(List<AutocompletePrediction>) onPredictions,
|
||||
required VoidCallback onOverlayHide,
|
||||
required Debouncer debouncer,
|
||||
}) {
|
||||
controller.addListener(() {
|
||||
_onAddressChanged(
|
||||
controller: controller,
|
||||
debouncer: debouncer,
|
||||
onPredictions: onPredictions,
|
||||
onOverlayHide: onOverlayHide,
|
||||
);
|
||||
});
|
||||
|
||||
focusNode.addListener(() {
|
||||
if (!focusNode.hasFocus) {
|
||||
Future.delayed(const Duration(milliseconds: 100), onOverlayHide);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _onAddressChanged({
|
||||
required TextEditingController controller,
|
||||
required Debouncer debouncer,
|
||||
required void Function(List<AutocompletePrediction>) onPredictions,
|
||||
required VoidCallback onOverlayHide,
|
||||
}) async {
|
||||
if (_isHandlingSelection || controller.text.length < 3) return;
|
||||
|
||||
debouncer.run(() async {
|
||||
try {
|
||||
final result = await _places.findAutocompletePredictions(
|
||||
controller.text,
|
||||
countries: ['us'],
|
||||
);
|
||||
|
||||
if (result.predictions.isNotEmpty) {
|
||||
onPredictions(result.predictions);
|
||||
} else {
|
||||
onOverlayHide();
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Prediction error: $e');
|
||||
onOverlayHide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> handlePlaceSelection({
|
||||
required AutocompletePrediction prediction,
|
||||
required TextEditingController addressController,
|
||||
required void Function(double? lat, double? lng) onLatLngRetrieved,
|
||||
required VoidCallback onOverlayHide,
|
||||
}) async {
|
||||
try {
|
||||
_isHandlingSelection = true;
|
||||
onOverlayHide();
|
||||
|
||||
final result = await _places.fetchPlace(
|
||||
prediction.placeId,
|
||||
fields: [PlaceField.Address, PlaceField.Location],
|
||||
);
|
||||
|
||||
final place = result.place;
|
||||
if (place != null) {
|
||||
addressController.text = place.address ?? prediction.fullText;
|
||||
onLatLngRetrieved(place.latLng?.lat, place.latLng?.lng);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Place fetch error: $e');
|
||||
} finally {
|
||||
_isHandlingSelection = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user