Showing
4 changed files
with
78 additions
and
50 deletions
... | @@ -41,6 +41,7 @@ class Results { | ... | @@ -41,6 +41,7 @@ class Results { |
41 | PlusCode? plusCode; | 41 | PlusCode? plusCode; |
42 | dynamic rating; | 42 | dynamic rating; |
43 | int? userRatingsTotal; | 43 | int? userRatingsTotal; |
44 | + bool isSelect = false; | ||
44 | 45 | ||
45 | Results( | 46 | Results( |
46 | {this.geometry, | 47 | {this.geometry, |
... | @@ -58,11 +59,11 @@ class Results { | ... | @@ -58,11 +59,11 @@ class Results { |
58 | this.openingHours, | 59 | this.openingHours, |
59 | this.plusCode, | 60 | this.plusCode, |
60 | this.rating, | 61 | this.rating, |
61 | - this.userRatingsTotal}); | 62 | + this.userRatingsTotal, |
63 | + this.isSelect = false}); | ||
62 | 64 | ||
63 | Results.fromJson(Map<String, dynamic> json) { | 65 | Results.fromJson(Map<String, dynamic> json) { |
64 | - geometry = | 66 | + geometry = json['geometry'] != null ? Geometry.fromJson(json['geometry']) : null; |
65 | - json['geometry'] != null ? Geometry.fromJson(json['geometry']) : null; | ||
66 | icon = json['icon']; | 67 | icon = json['icon']; |
67 | iconBackgroundColor = json['icon_background_color']; | 68 | iconBackgroundColor = json['icon_background_color']; |
68 | iconMaskBaseUri = json['icon_mask_base_uri']; | 69 | iconMaskBaseUri = json['icon_mask_base_uri']; |
... | @@ -79,11 +80,8 @@ class Results { | ... | @@ -79,11 +80,8 @@ class Results { |
79 | types = json['types'].cast<String>(); | 80 | types = json['types'].cast<String>(); |
80 | vicinity = json['vicinity']; | 81 | vicinity = json['vicinity']; |
81 | businessStatus = json['business_status']; | 82 | businessStatus = json['business_status']; |
82 | - openingHours = json['opening_hours'] != null | 83 | + openingHours = json['opening_hours'] != null ? OpeningHours.fromJson(json['opening_hours']) : null; |
83 | - ? OpeningHours.fromJson(json['opening_hours']) | 84 | + plusCode = json['plus_code'] != null ? PlusCode.fromJson(json['plus_code']) : null; |
84 | - : null; | ||
85 | - plusCode = | ||
86 | - json['plus_code'] != null ? PlusCode.fromJson(json['plus_code']) : null; | ||
87 | rating = json['rating']; | 85 | rating = json['rating']; |
88 | userRatingsTotal = json['user_ratings_total']; | 86 | userRatingsTotal = json['user_ratings_total']; |
89 | } | 87 | } |
... | @@ -125,10 +123,8 @@ class Geometry { | ... | @@ -125,10 +123,8 @@ class Geometry { |
125 | Geometry({this.location, this.viewport}); | 123 | Geometry({this.location, this.viewport}); |
126 | 124 | ||
127 | Geometry.fromJson(Map<String, dynamic> json) { | 125 | Geometry.fromJson(Map<String, dynamic> json) { |
128 | - location = | 126 | + location = json['location'] != null ? Location.fromJson(json['location']) : null; |
129 | - json['location'] != null ? Location.fromJson(json['location']) : null; | 127 | + viewport = json['viewport'] != null ? Viewport.fromJson(json['viewport']) : null; |
130 | - viewport = | ||
131 | - json['viewport'] != null ? Viewport.fromJson(json['viewport']) : null; | ||
132 | } | 128 | } |
133 | 129 | ||
134 | Map<String, dynamic> toJson() { | 130 | Map<String, dynamic> toJson() { |
... | @@ -169,10 +165,8 @@ class Viewport { | ... | @@ -169,10 +165,8 @@ class Viewport { |
169 | Viewport({this.northeast, this.southwest}); | 165 | Viewport({this.northeast, this.southwest}); |
170 | 166 | ||
171 | Viewport.fromJson(Map<String, dynamic> json) { | 167 | Viewport.fromJson(Map<String, dynamic> json) { |
172 | - northeast = | 168 | + northeast = json['northeast'] != null ? Location.fromJson(json['northeast']) : null; |
173 | - json['northeast'] != null ? Location.fromJson(json['northeast']) : null; | 169 | + southwest = json['southwest'] != null ? Location.fromJson(json['southwest']) : null; |
174 | - southwest = | ||
175 | - json['southwest'] != null ? Location.fromJson(json['southwest']) : null; | ||
176 | } | 170 | } |
177 | 171 | ||
178 | Map<String, dynamic> toJson() { | 172 | Map<String, dynamic> toJson() { | ... | ... |
... | @@ -22,12 +22,10 @@ class AddressSelectPage extends StatefulWidget { | ... | @@ -22,12 +22,10 @@ class AddressSelectPage extends StatefulWidget { |
22 | 22 | ||
23 | class AddressSelectPageState extends State<AddressSelectPage> { | 23 | class AddressSelectPageState extends State<AddressSelectPage> { |
24 | List<nearby.Results> _list = []; | 24 | List<nearby.Results> _list = []; |
25 | - int _index = 0; | ||
26 | final ScrollController _controller = ScrollController(); | 25 | final ScrollController _controller = ScrollController(); |
27 | - LatLng _center = const LatLng(45.521563, -122.677433); | 26 | + LatLng? _center; |
28 | late GoogleMapController mapController; | 27 | late GoogleMapController mapController; |
29 | bool isLoading = false; | 28 | bool isLoading = false; |
30 | - int _markerIdCounter = 1; | ||
31 | Map<MarkerId, Marker> markers = <MarkerId, Marker>{}; | 29 | Map<MarkerId, Marker> markers = <MarkerId, Marker>{}; |
32 | late StreamSubscription _locationSubscription; | 30 | late StreamSubscription _locationSubscription; |
33 | String radius = "1000"; | 31 | String radius = "1000"; |
... | @@ -65,44 +63,38 @@ class AddressSelectPageState extends State<AddressSelectPage> { | ... | @@ -65,44 +63,38 @@ class AddressSelectPageState extends State<AddressSelectPage> { |
65 | return; | 63 | return; |
66 | } | 64 | } |
67 | } | 65 | } |
68 | - | 66 | + var currentLocation = await location.getLocation(); |
69 | - _locationSubscription = location.onLocationChanged.listen((LocationData currentLocation) { | ||
70 | _center = LatLng(currentLocation.latitude!, currentLocation.longitude!); | 67 | _center = LatLng(currentLocation.latitude!, currentLocation.longitude!); |
71 | - Log.e("currentLocation.latitude ${currentLocation.latitude}"); | ||
72 | getNearbyPlaces(""); | 68 | getNearbyPlaces(""); |
73 | - }); | 69 | + _goToCurrentCenter(); |
74 | } | 70 | } |
75 | 71 | ||
76 | void getNearbyPlaces(String keyword) async { | 72 | void getNearbyPlaces(String keyword) async { |
77 | String uri = | 73 | String uri = |
78 | - '${'https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${_center.latitude},${_center.longitude}&radius=$radius'}&key=$apiKey&keyword=$keyword'; | 74 | + '${'https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${_center?.latitude},${_center?.longitude}&radius=$radius'}&key=$apiKey&keyword=$keyword'; |
75 | + print(uri); | ||
79 | var url = Uri.parse(uri); | 76 | var url = Uri.parse(uri); |
80 | var response = await http.post(url); | 77 | var response = await http.post(url); |
81 | nearbyPlacesResponse = nearby.NearbyPlacesResponse.fromJson(jsonDecode(response.body)); | 78 | nearbyPlacesResponse = nearby.NearbyPlacesResponse.fromJson(jsonDecode(response.body)); |
82 | _list = nearbyPlacesResponse.results!; | 79 | _list = nearbyPlacesResponse.results!; |
80 | + if (_list.isNotEmpty) { | ||
81 | + selectItemLocation(_list[0]); | ||
82 | + } | ||
83 | setState(() { | 83 | setState(() { |
84 | isLoading = false; | 84 | isLoading = false; |
85 | }); | 85 | }); |
86 | + buildMarkers(); | ||
86 | } | 87 | } |
87 | 88 | ||
88 | void _onMapCreated(GoogleMapController controller) { | 89 | void _onMapCreated(GoogleMapController controller) { |
89 | mapController = controller; | 90 | mapController = controller; |
90 | - final String markerIdVal = 'marker_id_$_markerIdCounter'; | ||
91 | - _markerIdCounter++; | ||
92 | - final MarkerId markerId = MarkerId(markerIdVal); | ||
93 | - final Marker marker = Marker( | ||
94 | - markerId: markerId, | ||
95 | - position: _center, | ||
96 | - ); | ||
97 | - mapController.moveCamera(CameraUpdate.newLatLng(_center)); | ||
98 | - setState(() { | ||
99 | - markers[markerId] = marker; | ||
100 | - }); | ||
101 | getNearbyPlaces(""); | 91 | getNearbyPlaces(""); |
102 | } | 92 | } |
103 | 93 | ||
104 | void _goToCurrentCenter() { | 94 | void _goToCurrentCenter() { |
105 | - mapController.animateCamera(CameraUpdate.newLatLng(_center)); | 95 | + if (_center != null) { |
96 | + mapController.moveCamera(CameraUpdate.newLatLng(_center!)); | ||
97 | + } | ||
106 | } | 98 | } |
107 | 99 | ||
108 | @override | 100 | @override |
... | @@ -113,12 +105,12 @@ class AddressSelectPageState extends State<AddressSelectPage> { | ... | @@ -113,12 +105,12 @@ class AddressSelectPageState extends State<AddressSelectPage> { |
113 | itemCount: _list.length, | 105 | itemCount: _list.length, |
114 | separatorBuilder: (_, index) => const Divider(), | 106 | separatorBuilder: (_, index) => const Divider(), |
115 | itemBuilder: (_, index) { | 107 | itemBuilder: (_, index) { |
108 | + var item = _list[index]; | ||
116 | return _AddressItem( | 109 | return _AddressItem( |
117 | - isSelected: _index == index, | 110 | + isSelected: item.isSelect, |
118 | - date: _list[index], | 111 | + date: item, |
119 | onTap: () { | 112 | onTap: () { |
120 | - _index = index; | 113 | + selectItemLocation(item); |
121 | - setState(() {}); | ||
122 | }, | 114 | }, |
123 | ); | 115 | ); |
124 | }, | 116 | }, |
... | @@ -130,25 +122,21 @@ class AddressSelectPageState extends State<AddressSelectPage> { | ... | @@ -130,25 +122,21 @@ class AddressSelectPageState extends State<AddressSelectPage> { |
130 | onPressed: (text) async { | 122 | onPressed: (text) async { |
131 | isLoading = true; | 123 | isLoading = true; |
132 | _controller.animateTo(0.0, duration: const Duration(milliseconds: 10), curve: Curves.ease); | 124 | _controller.animateTo(0.0, duration: const Duration(milliseconds: 10), curve: Curves.ease); |
133 | - _index = 0; | ||
134 | // 构造检索参数 | 125 | // 构造检索参数 |
135 | getNearbyPlaces(text); | 126 | getNearbyPlaces(text); |
136 | }, | 127 | }, |
137 | ); | 128 | ); |
138 | var map = GoogleMap( | 129 | var map = GoogleMap( |
139 | onMapCreated: _onMapCreated, | 130 | onMapCreated: _onMapCreated, |
140 | - initialCameraPosition: CameraPosition(target: _center, zoom: 16.0), | 131 | + initialCameraPosition: CameraPosition(target: _center ?? const LatLng(45.521563, -122.677433), zoom: 16.0), |
141 | markers: Set<Marker>.of(markers.values), | 132 | markers: Set<Marker>.of(markers.values), |
142 | ).expanded(flex: 9); | 133 | ).expanded(flex: 9); |
134 | + | ||
143 | return Scaffold( | 135 | return Scaffold( |
144 | resizeToAvoidBottomInset: false, | 136 | resizeToAvoidBottomInset: false, |
145 | appBar: searchBar, | 137 | appBar: searchBar, |
146 | body: Column( | 138 | body: Column( |
147 | - children: <Widget>[ | 139 | + children: <Widget>[map, listHolder, initButton()], |
148 | - map, | ||
149 | - listHolder, | ||
150 | - initButton(), | ||
151 | - ], | ||
152 | ).safe(), | 140 | ).safe(), |
153 | ); | 141 | ); |
154 | } | 142 | } |
... | @@ -156,15 +144,58 @@ class AddressSelectPageState extends State<AddressSelectPage> { | ... | @@ -156,15 +144,58 @@ class AddressSelectPageState extends State<AddressSelectPage> { |
156 | initButton() { | 144 | initButton() { |
157 | return MyButton( | 145 | return MyButton( |
158 | onPressed: () { | 146 | onPressed: () { |
159 | - if (_list.isEmpty) { | 147 | + var selected = _list.where((element) => element.isSelect); |
148 | + if (selected.isEmpty) { | ||
160 | Toast.show('未选择地址!'); | 149 | Toast.show('未选择地址!'); |
161 | return; | 150 | return; |
162 | } | 151 | } |
163 | - NavigatorUtils.goBackWithParams(context, _list[_index]); | 152 | + |
153 | + NavigatorUtils.goBackWithParams(context, selected.first); | ||
164 | }, | 154 | }, |
165 | text: '确认选择地址', | 155 | text: '确认选择地址', |
166 | ); | 156 | ); |
167 | } | 157 | } |
158 | + | ||
159 | + void buildMarkers() { | ||
160 | + markers.clear(); | ||
161 | + for (var value in _list) { | ||
162 | + final MarkerId markerId = MarkerId(buildMarkerId(value)); | ||
163 | + final Marker marker = Marker( | ||
164 | + icon: value.isSelect ? BitmapDescriptor.defaultMarker : BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue), | ||
165 | + markerId: markerId, | ||
166 | + position: buildMarkerLocation(value), | ||
167 | + ); | ||
168 | + markers[markerId] = marker; | ||
169 | + } | ||
170 | + setState(() {}); | ||
171 | + } | ||
172 | + | ||
173 | + String buildMarkerId(nearby.Results value) { | ||
174 | + var lat = value.geometry?.location?.lat; | ||
175 | + var lng = value.geometry?.location?.lng; | ||
176 | + return "$lat-$lng"; | ||
177 | + } | ||
178 | + | ||
179 | + LatLng buildMarkerLocation(nearby.Results value) { | ||
180 | + var lat = value.geometry?.location?.lat; | ||
181 | + var lng = value.geometry?.location?.lng; | ||
182 | + return LatLng(lat ?? 0, lng ?? 0); | ||
183 | + } | ||
184 | + | ||
185 | + void selectItemLocation(nearby.Results item) { | ||
186 | + for (var element in _list) { | ||
187 | + element.isSelect = false; | ||
188 | + } | ||
189 | + item.isSelect = true; | ||
190 | + var lat = item.geometry?.location?.lat; | ||
191 | + var lng = item.geometry?.location?.lng; | ||
192 | + if (lat != null && lng != null) { | ||
193 | + _center = LatLng(lat, lng); | ||
194 | + } | ||
195 | + _goToCurrentCenter(); | ||
196 | + setState(() {}); | ||
197 | + buildMarkers(); | ||
198 | + } | ||
168 | } | 199 | } |
169 | 200 | ||
170 | class _AddressItem extends StatelessWidget { | 201 | class _AddressItem extends StatelessWidget { | ... | ... |
... | @@ -125,7 +125,7 @@ dependencies: | ... | @@ -125,7 +125,7 @@ dependencies: |
125 | google_fonts: ^3.0.1 | 125 | google_fonts: ^3.0.1 |
126 | wakelock: ^0.6.1+2 | 126 | wakelock: ^0.6.1+2 |
127 | location: ^4.4.0 | 127 | location: ^4.4.0 |
128 | - google_maps_flutter: ^2.1.10 | 128 | + google_maps_flutter: ^2.2.1 |
129 | http: ^0.13.5 | 129 | http: ^0.13.5 |
130 | 130 | ||
131 | dependency_overrides: | 131 | dependency_overrides: | ... | ... |
-
Please register or login to post a comment