// @dart=2.9
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:geolocator/geolocator.dart';
import 'package:intl/intl.dart';
import 'package:geocoding/geocoding.dart';
class Weather extends StatefulWidget {
@override
_WeatherState createState() => _WeatherState();
}
class _WeatherState extends State<Weather> {
int temperature;
var minTemperatureForecast = new List(7);
var maxTemperatureForecast = new List(7);
String location = 'San Francisco';
int woeid = 2487956;
String weather = 'clear';
String abbreviation = '';
var abbreviationForecast = new List(7);
String errorMessage = '';
final Geolocator geolocator = Geolocator()..forceAndroidLocationmanager;
Position _currentPosition;
String _currentAddress;
String searchApiUrl =
'https://www.metaweather.com/api/location/search/?query=';
String locationApiUrl = 'https://www.metaweather.com/api/location/';
get geocoding => null;
initState() {
super.initState();
fetchLocation();
fetchLocationDay();
}
void fetchSearch(String input) async {
try {
var searchResult = await http.get(Uri.parse(searchApiUrl + input));
var result = json.decode(searchResult.body)[0];
setState(() {
location = result["title"];
woeid = result["woeid"];
errorMessage = '';
});
} catch (error) {
setState(() {
errorMessage =
"Sorry,we don't have data about this city. Try another one.";
});
}
}
void fetchLocation() async {
var locationResult = await http.get(Uri.parse(locationApiUrl + woeid.toString()));
var result = json.decode(locationResult.body);
var consolidated_weather = result["consolidated_weather"];
var data = consolidated_weather[0];
setState(() {
temperature = data["the_temp"].round();
weather = data["weather_state_name"].replaceAll(' ','').toLowerCase();
abbreviation = data["weather_state_abbr"];
});
}
void fetchLocationDay() async {
var today = new DateTime.now();
for (var i = 0; i < 7; i++) {
var locationDayResult = await http.get(Uri.parse(locationApiUrl +
woeid.toString() +
'/' +
new DateFormat('y/M/d')
.format(today.add(new Duration(days: i + 1)))
.toString()));
var result = json.decode(locationDayResult.body);
var data = result[0];
setState(() {
minTemperatureForecast[i] = data["min_temp"].round();
maxTemperatureForecast[i] = data["max_temp"].round();
abbreviationForecast[i] = data["weather_state_abbr"];
});
}
}
void onTextFieldSubmitted(String input) async {
await fetchSearch(input);
await fetchLocation();
await fetchLocationDay();
}
_getcurrentLocation() {
Geolocator
.getcurrentPosition(desiredaccuracy: Locationaccuracy.best,forceAndroidLocationmanager: true)
.then((Position position) {
setState(() {
_currentPosition = position;
});
_getaddressFromLatLng();
}).catchError((e) {
print(e);
});
}
_getaddressFromLatLng() async {
try {
List<Placemark> p = await geocoding.placemarkFromCoordinates(
_currentPosition.latitude,_currentPosition.longitude);
Placemark place = p[0];
setState(() {
_currentAddress =
"${place.locality},${place.postalCode},${place.country}";
});
onTextFieldSubmitted(place.locality);
print(place.locality);
} catch (e) {
print(e);
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedmodeBanner: false,home: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/$weather.png'),fit: BoxFit.cover,colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.6),Blendmode.dstATop),),child: temperature == null
? Center(child: CircularProgressIndicator())
: Scaffold(
appBar: AppBar(
actions: <Widget>[
Padding(
padding: EdgeInsets.only(right: 300.0),child: IconButton(
onpressed: () {
Navigator.pop(context);
},icon: Icon(Icons.arrow_back,size: 40.0,color: Colors.black,Padding(
padding: const EdgeInsets.only(right: 5.0),child: GestureDetector(
onTap: () {
_getcurrentLocation();
},child: Icon(Icons.location_city,size: 36.0),)
],backgroundColor: Colors.transparent,elevation: 0.0,resizeToAvoidBottomInset: false,body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[
Column(
children: <Widget>[
Center(
child: Image.network(
'https://www.metaweather.com/static/img/weather/png/' +
abbreviation +
'.png',width: 100,Center(
child: Text(
temperature.toString() + ' °C',style: TextStyle(
color: Colors.white,fontSize: 60.0),Center(
child: Text(
location,fontSize: 40.0),],SingleChildScrollView(
scrollDirection: Axis.horizontal,child: Row(
children: <Widget>[
// ignore: sdk_version_ui_as_code
for (var i = 0; i < 7; i++)
forecastElement(
i + 1,abbreviationForecast[i],minTemperatureForecast[i],maxTemperatureForecast[i]),Column(
children: <Widget>[
Container(
width: 300,child: TextField(
onSubmitted: (String input) {
onTextFieldSubmitted(input);
},style:
TextStyle(color: Colors.white,fontSize: 25),decoration: InputDecoration(
hintText: 'Search another location...',hintStyle: TextStyle(
color: Colors.white,fontSize: 18.0),prefixIcon:
Icon(Icons.search,color: Colors.white),Padding(
padding:
const EdgeInsets.only(right: 32.0,left: 32.0),child: Text(errorMessage,textAlign: TextAlign.center,style: TextStyle(
color: Colors.redaccent,fontSize:
Platform.isAndroid ? 15.0 : 20.0)),)
],)),);
}
}
/// Contains detailed placemark information.
class Placemark {
/// Constructs an instance with the given values for testing. [Placemark]
/// instances constructed this way won't actually reflect any real information
/// from the platform,just whatever was passed in at construction time.
Placemark(
{this.name,this.isoCountryCode,this.country,this.postalCode,this.administrativeArea,this.subAdministrativeArea,this.locality,this.subLocality,this.thoroughfare,this.subThoroughfare,this.position});
Placemark._(
{this.name,this.position});
/// The name of the placemark.
final String name;
/// The abbreviated country name,according to the two letter (alpha-2) [ISO standard](https://www.iso.org/iso-3166-country-codes.html).
final String isoCountryCode;
/// The name of the country associated with the placemark.
final String country;
/// The postal code associated with the placemark.
final String postalCode;
/// The name of the state or province associated with the placemark.
final String administrativeArea;
/// Additional administrative area information for the placemark.
final String subAdministrativeArea;
/// The name of the city associated with the placemark.
final String locality;
/// Additional city-level information for the placemark.
final String subLocality;
/// The street address associated with the placemark.
final String thoroughfare;
/// Additional street address information for the placemark.
final String subThoroughfare;
/// The geocoordinates associated with the placemark.
final Position position;
@override
bool operator ==(o) =>
o is Placemark &&
o.administrativeArea == administrativeArea &&
o.country == country &&
o.isoCountryCode == isoCountryCode &&
o.locality == locality &&
o.name == name &&
o.position == position &&
o.postalCode == postalCode &&
o.subAdministrativeArea == subAdministrativeArea &&
o.subLocality == subLocality &&
o.subThoroughfare == subThoroughfare &&
o.thoroughfare == thoroughfare;
@override
int get hashCode =>
administrativeArea.hashCode ^
country.hashCode ^
isoCountryCode.hashCode ^
locality.hashCode ^
name.hashCode ^
position.hashCode ^
postalCode.hashCode ^
subAdministrativeArea.hashCode ^
subLocality.hashCode ^
subThoroughfare.hashCode ^
thoroughfare.hashCode;
/// Converts a list of [Map] instances to a list of [Placemark] instances.
static List<Placemark> fromMaps(dynamic message) {
if (message == null) {
throw ArgumentError('The parameter \'message\' should not be null.');
}
final List<Placemark> list = message.map<Placemark>(fromMap).toList();
return list;
}
/// Converts the supplied [Map] to an instance of the [Placemark] class.
static Placemark fromMap(dynamic message) {
if (message == null) {
throw ArgumentError('The parameter \'message\' should not be null.');
}
final Map<dynamic,dynamic> placemarkMap = message;
return Placemark._(
name: placemarkMap['name'] ?? '',isoCountryCode: placemarkMap['isoCountryCode'] ?? '',country: placemarkMap['country'] ?? '',postalCode: placemarkMap['postalCode'] ?? '',administrativeArea: placemarkMap['administrativeArea'] ?? '',subAdministrativeArea: placemarkMap['subAdministrativeArea'] ?? '',locality: placemarkMap['locality'] ?? '',subLocality: placemarkMap['subLocality'] ?? '',thoroughfare: placemarkMap['thoroughfare'] ?? '',subThoroughfare: placemarkMap['subThoroughfare'] ?? '',position: placemarkMap['position'] != null
? Position.fromMap(placemarkMap['position'])
: null,);
}
/// Converts the [Placemark] instance into a [Map] instance that can be serialized to JSON.
Map<String,dynamic> toJson() => {
'name': name,'isoCountryCode': isoCountryCode,'country': country,'postalCode': postalCode,'administrativeArea': administrativeArea,'subAdministrativeArea': subAdministrativeArea,'locality': locality,'subLocality': subLocality,'thoroughfare': thoroughfare,'subThoroughfare': subThoroughfare,'position': position.toJson()
};
}
Widget forecastElement(
daysFromNow,abbreviation,minTemperature,maxTemperature) {
var now = new DateTime.now();
var oneDayFromNow = now.add(new Duration(days: daysFromNow));
return Padding(
padding: const EdgeInsets.only(left: 16.0),child: Container(
decoration: BoxDecoration(
color: Color.fromRGBO(205,212,228,0.2),borderRadius: BorderRadius.circular(10),child: Padding(
padding: const EdgeInsets.all(16.0),child: Column(
children: <Widget>[
Text(
new DateFormat.E().format(oneDayFromNow),style: TextStyle(color: Colors.white,Text(
new DateFormat.MMMd().format(oneDayFromNow),fontSize: 20),Padding(
padding: const EdgeInsets.only(top: 16.0,bottom: 16.0),child: Image.network(
'https://www.metaweather.com/static/img/weather/png/' +
abbreviation +
'.png',width: 50,Text(
'High: ' + maxTemperature.toString() + ' °C',fontSize: 20.0),Text(
'Low: ' + minTemperature.toString() + ' °C',);
}
我正在尝试使用地标在我的 flutter 应用程序中获取用户位置。我已经导入了运行应用程序所需的所有必要依赖项,但我仍然在地理定位器地标中收到错误消息。我不知道该怎么办。
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:ft06/requests/google_maps_requests.dart';
class AppState with ChangeNotifier {
static LatLng _initialPosition;
LatLng _lastPosition = _initialPosition;
bool locationServiceactive = true;
final Set<Marker> _markers = {};
final Set<Polyline> _polyLines = {};
GoogleMapController _mapController;
GoogleMapsServices _googleMapsServices = GoogleMapsServices();
TextEditingController locationController = TextEditingController();
TextEditingController destinationController = TextEditingController();
LatLng get initialPosition => _initialPosition;
LatLng get lastPosition => _lastPosition;
GoogleMapsServices get googleMapsServices => _googleMapsServices;
GoogleMapController get mapController => _mapController;
Set<Marker> get markers => _markers;
Set<Polyline> get polyLines => _polyLines;
AppState() {
_getUserLocation();
_loadingInitialPosition();
}
// ! TO GET THE USERS LOCATION
void _getUserLocation() async {
print("GET USER METHOD RUNNING =========");
Position position = await Geolocator()
.getcurrentPosition(desiredaccuracy:Locationaccuracy.high);
List<Placemark> placemark = await Geolocator()
.placemarkFromCoordinates(position.latitude,position.longitude);
_initialPosition = LatLng(position.latitude,position.longitude);
print("the latitude is: ${position.longitude} and th longitude is: ${position.longitude} ");
print("initial position is : ${_initialPosition.toString()}");
locationController.text = placemark[0].name;
notifyListeners();
}
终端上的实际错误输出在这里: