added search functionality
This commit is contained in:
parent
911c2738aa
commit
799d1cb335
@ -1,16 +1,24 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter_map/flutter_map.dart';
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
|
import 'package:latlong2/latlong.dart';
|
||||||
|
|
||||||
class MapState extends ChangeNotifier {
|
class MapState extends ChangeNotifier {
|
||||||
bool _isCurrentlyLoading = false;
|
bool _isCurrentlyLoading = false;
|
||||||
|
LatLng? _activeMarker;
|
||||||
final MapController _mapController = MapController();
|
final MapController _mapController = MapController();
|
||||||
final Geolocator _geolocator = Geolocator();
|
final Geolocator _geolocator = Geolocator();
|
||||||
|
|
||||||
bool get isCurrentlyLoading => _isCurrentlyLoading;
|
bool get isCurrentlyLoading => _isCurrentlyLoading;
|
||||||
|
LatLng? get getActiveMarker => _activeMarker;
|
||||||
MapController get getMapController => _mapController;
|
MapController get getMapController => _mapController;
|
||||||
Geolocator get getGeolocator => _geolocator;
|
Geolocator get getGeolocator => _geolocator;
|
||||||
|
|
||||||
|
void setActiveMarker(LatLng? marker) {
|
||||||
|
_activeMarker = marker;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
void setLoading(bool loading) {
|
void setLoading(bool loading) {
|
||||||
_isCurrentlyLoading = loading;
|
_isCurrentlyLoading = loading;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -4,9 +4,11 @@ import 'package:app/state/timeStatusState.dart';
|
|||||||
import 'package:app/util/loadingContainer.dart';
|
import 'package:app/util/loadingContainer.dart';
|
||||||
import 'package:app/util/watchState.dart';
|
import 'package:app/util/watchState.dart';
|
||||||
import 'package:app/view/appInfo.dart';
|
import 'package:app/view/appInfo.dart';
|
||||||
|
import 'package:app/view/locationSearch.dart';
|
||||||
import 'package:app/view/status.dart';
|
import 'package:app/view/status.dart';
|
||||||
import 'package:app/view/map.dart';
|
import 'package:app/view/map.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -52,8 +54,16 @@ class _HomePageState extends State<HomeView> {
|
|||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.search),
|
icon: const Icon(Icons.search),
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
|
LatLng? latLng = await showSearch<LatLng?>(
|
||||||
|
context: context,
|
||||||
|
delegate: LocationSearchDelegate(),
|
||||||
|
);
|
||||||
|
MapState mapState = context.obtainState<MapState>();
|
||||||
|
mapState.setActiveMarker(latLng);
|
||||||
|
if (latLng != null) {
|
||||||
|
mapState.getMapController.move(latLng, 16);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
|
60
lib/view/locationSearch.dart
Normal file
60
lib/view/locationSearch.dart
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:latlong2/latlong.dart';
|
||||||
|
import 'package:osm_nominatim/osm_nominatim.dart';
|
||||||
|
|
||||||
|
class LocationSearchDelegate extends SearchDelegate<LatLng?> {
|
||||||
|
@override
|
||||||
|
List<Widget>? buildActions(BuildContext context) {
|
||||||
|
return [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.clear),
|
||||||
|
onPressed: () => query = '',
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget? buildLeading(BuildContext context) {
|
||||||
|
return IconButton(
|
||||||
|
icon: const Icon(Icons.arrow_back),
|
||||||
|
onPressed: () => close(context, null),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildResults(BuildContext context) {
|
||||||
|
return FutureBuilder<List<Place>>(
|
||||||
|
future: query.isEmpty ? Future.value([]) : Nominatim.searchByName(
|
||||||
|
query: query,
|
||||||
|
limit: 10,
|
||||||
|
language: 'de',
|
||||||
|
// https://gist.github.com/graydon/11198540#file-country-bounding-boxes-py-L45
|
||||||
|
viewBox: ViewBox(54.983104153, 15.0169958839, 47.3024876979, 5.98865807458)
|
||||||
|
),
|
||||||
|
builder: (BuildContext context, AsyncSnapshot<List<Place>> snapshot) {
|
||||||
|
switch (snapshot.connectionState) {
|
||||||
|
case ConnectionState.waiting:
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
case ConnectionState.active:
|
||||||
|
case ConnectionState.none:
|
||||||
|
case ConnectionState.done:
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: snapshot.data?.length ?? 0,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
Place place = snapshot.data![index];
|
||||||
|
return ListTile(
|
||||||
|
title: Text(place.displayName),
|
||||||
|
onTap: () => close(context, LatLng(place.lat, place.lon)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildSuggestions(BuildContext context) {
|
||||||
|
return buildResults(context);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:app/extensions/obtainProviderExtension.dart';
|
import 'package:app/extensions/obtainProviderExtension.dart';
|
||||||
import 'package:app/state/mapState.dart';
|
import 'package:app/state/mapState.dart';
|
||||||
|
import 'package:app/util/watchState.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_map/flutter_map.dart';
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
@ -36,7 +37,19 @@ class _MapViewState extends State<MapView> {
|
|||||||
Client(),
|
Client(),
|
||||||
when: (response) => response.statusCode == 502)
|
when: (response) => response.statusCode == 502)
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
WatchState<MapState>((context, state) => state.getActiveMarker != null ? MarkerLayer(
|
||||||
|
markers: [
|
||||||
|
Marker(
|
||||||
|
point: state.getActiveMarker!,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.location_on,
|
||||||
|
color: Colors.red,
|
||||||
|
size: 48,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
) : const SizedBox.shrink())
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -384,6 +384,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
|
osm_nominatim:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: osm_nominatim
|
||||||
|
sha256: "037f1af3abee92cf34e33b562cec1acbb0210234b1bdf3d8975bdef3849e6287"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -43,6 +43,7 @@ dependencies:
|
|||||||
http: ^1.2.1
|
http: ^1.2.1
|
||||||
flutter_timer_countdown: ^1.0.7
|
flutter_timer_countdown: ^1.0.7
|
||||||
geolocator: ^11.0.0
|
geolocator: ^11.0.0
|
||||||
|
osm_nominatim: ^3.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Reference in New Issue
Block a user