An app that detects current location latitude and longitude, then fetch weather temperature for current city, also you can search for any city.
pubsec.yml
name: clima
description: A new Flutter application.
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
geolocator: ^5.1.5
http: ^0.12.0+2
flutter_spinkit: ^4.1.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
assets:
- images/
fonts:
- family: Spartan MB
fonts:
- asset: fonts/SpartanMB-Black.otf
weight: 900
lib/main.dart
import 'package:flutter/material.dart';
import 'package:clima/screens/loading_screen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: LoadingScreen(),
);
}
}
lib/screens/loading_screen.dart
import 'package:flutter/material.dart';
import 'package:clima/screens/location_screen.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:clima/services/weather.dart';
class LoadingScreen extends StatefulWidget {
@override
_LoadingScreenState createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
@override
void initState(){
super.initState();
getWeather();
}
void getWeather() async{
var weatherData = await WeatherModel().getWeatherLocation();
Navigator.push(context, MaterialPageRoute(builder: (context) => LocationScreen(weatherData: weatherData)));
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Builder(
builder: (context) => Center(
child: SpinKitWave(
color: Colors.white,
size: 40,
),
),
),
);
}
}
lib/screens/location_screen.dart
import 'package:clima/screens/city_screen.dart';
import 'package:flutter/material.dart';
import 'package:clima/utilities/constants.dart';
import 'package:clima/services/weather.dart';
class LocationScreen extends StatefulWidget {
LocationScreen({this.weatherData});
final weatherData;
@override
_LocationScreenState createState() => _LocationScreenState();
}
class _LocationScreenState extends State<LocationScreen> {
int temperature;
int condition;
String cityName;
String cityIcon;
String weatherMessage;
@override
void initState(){
super.initState();
updateUI(widget.weatherData);
}
updateUI(dynamic weatherData){
setState(() {
temperature = 0;
condition = 0;
cityName = 'Phone';
cityIcon = 'Error';
if(weatherData == null){
weatherMessage = 'Something wrong, May be internet problem';
return;
}
double localTemp = weatherData['main']['temp'];
temperature = localTemp.toInt();
condition = weatherData['weather'][0]['id'];
cityName = weatherData['name'];
WeatherModel weatherModel = WeatherModel();
cityIcon = weatherModel.getWeatherIcon(condition);
weatherMessage = weatherModel.getMessage(temperature);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Builder(
builder: (context) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/location_background.jpg'),
fit: BoxFit.cover,
colorFilter: ColorFilter.mode(
Colors.white.withOpacity(0.8), BlendMode.dstATop),
),
),
constraints: BoxConstraints.expand(),
child: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FlatButton(
onPressed: () async {
var weatherData = await WeatherModel().getWeatherLocation();
updateUI(weatherData);
Scaffold.of(context).showSnackBar(SnackBar(content: Text('Weather Data has been updated.',), duration: Duration(milliseconds: 1000),),);
},
child: Icon(
Icons.near_me,
size: 40.0,
),
),
FlatButton(
onPressed: () async{
String cityName = await Navigator.push(context, MaterialPageRoute(builder: (context) => CityScreen()));
if(cityName != null){
var weatherData = await WeatherModel().getCityWeather(cityName);
updateUI(weatherData);
}
},
child: Icon(
Icons.location_city,
size: 40.0,
),
),
],
),
Padding(
padding: EdgeInsets.only(left: 15.0),
child: Row(
children: <Widget>[
Text(
'$temperature°',
style: kTempTextStyle,
),
Text(
cityIcon,
style: kConditionTextStyle,
),
],
),
),
Padding(
padding: EdgeInsets.only(right: 15.0),
child: Text(
'$weatherMessage in $cityName',
textAlign: TextAlign.right,
style: kMessageTextStyle,
),
),
],
),
),
),
),
);
}
}
lib/screens/city_screen.dart
import 'package:flutter/material.dart';
import 'package:clima/utilities/constants.dart';
class CityScreen extends StatefulWidget {
@override
_CityScreenState createState() => _CityScreenState();
}
class _CityScreenState extends State<CityScreen> {
String cityName;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/city_background.jpg'),
fit: BoxFit.cover,
),
),
constraints: BoxConstraints.expand(),
child: SafeArea(
child: Column(
children: <Widget>[
Align(
alignment: Alignment.topLeft,
child: FlatButton(
onPressed: () {
Navigator.pop(context);
},
child: Icon(
Icons.arrow_back_ios,
size: 50.0,
),
),
),
Container(
padding: EdgeInsets.all(20.0),
child: TextField(
style: TextStyle(
color: Colors.black
),
decoration: kTextFieldInputDecoration,
onChanged: (value){
cityName = value;
},
),
),
FlatButton(
onPressed: () {
Navigator.pop(context, cityName);
},
child: Text(
'Get Weather',
style: kButtonTextStyle,
),
),
],
),
),
),
);
}
}
lib/services/location.dart
import 'package:geolocator/geolocator.dart';
class Location{
double lattitude;
double longitude;
Future getCurrentLocation() async {
try{
Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.lowest);
this.lattitude = position.latitude;
this.longitude = position.longitude;
}catch(e){
print(e);
}
}
}
lib/services/networking.dart
import 'dart:convert';
import 'package:http/http.dart' as Http;
class NetworkHelper{
NetworkHelper(this.url);
final String url;
Future getData() async{
Http.Response response;
try{
response = await Http.get(url);
}catch(e){
return null;
}
if(response.statusCode == 200) {
return jsonDecode(response.body);
}else{
print('Response was not 200');
}
}
}
lib/services/weather.dart
import 'package:clima/services/location.dart';
import 'package:clima/services/networking.dart';
class WeatherModel {
String apiKey = 'c8ce20542b396ef0d2b4a37f9bf8c052';
String openWeatherMapURL = 'https://api.openweathermap.org/data/2.5/weather';
Future getWeatherLocation() async{
Location location = Location();
await location.getCurrentLocation();
NetworkHelper networkHelper = NetworkHelper('$openWeatherMapURL?lat=${location.lattitude}&lon=${location.longitude}&units=metric&appid=$apiKey');
return networkHelper.getData();
}
Future getCityWeather(String cityName) async{
Location location = Location();
await location.getCurrentLocation();
NetworkHelper networkHelper = NetworkHelper('$openWeatherMapURL?q=${Uri.encodeComponent(cityName)}&units=metric&appid=$apiKey');
return networkHelper.getData();
}
String getWeatherIcon(int condition) {
if (condition < 300) {
return '๐ฉ';
} else if (condition < 400) {
return '๐ง';
} else if (condition < 600) {
return '☔️';
} else if (condition < 700) {
return '☃️';
} else if (condition < 800) {
return '๐ซ';
} else if (condition == 800) {
return '☀️';
} else if (condition <= 804) {
return '☁️';
} else {
return '๐คท';
}
}
String getMessage(int temp) {
if (temp > 25) {
return 'It\'s ๐ฆ time';
} else if (temp > 20) {
return 'Time for shorts and ๐';
} else if (temp < 10) {
return 'You\'ll need ๐งฃ and ๐งค';
} else {
return 'Bring a ๐งฅ just in case';
}
}
}
lib/utilities/constant.dart
import 'package:flutter/material.dart';
const kTempTextStyle = TextStyle(
fontFamily: 'Spartan MB',
fontSize: 80.0,
);
const kMessageTextStyle = TextStyle(
fontFamily: 'Spartan MB',
fontSize: 40.0,
);
const kButtonTextStyle = TextStyle(
fontSize: 30.0,
fontFamily: 'Spartan MB',
);
const kConditionTextStyle = TextStyle(
fontSize: 80.0,
);
const kTextFieldInputDecoration = InputDecoration(
filled: true,
fillColor: Colors.white,
icon: Icon(Icons.location_city, color: Colors.yellow,),
hintText: 'Enter City Name',
hintStyle: TextStyle(
color: Colors.grey,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide.none,
),
);
Find me on:
https://twitter.com/naimurhasanrwd
Comments
Post a Comment