FLUTTER İLE HAVA DURUMU UYGULAMASI
Merhabalar bugün size Flutter kullanarak yapmış olduğum basit bir hava durumu uygulamasını göstereceğim.
Bu uygulama ile API'dan veri çekip bunu ekrana basmayı öğreneceğiz.
Öncelikle bize şehir ararken yardımcı olması için AutoComplete widget'ını kullanacağız. Bu widget'a liste tipinde bir değişken vermemiz gerekiyor. Bunun için bir listeye tüm şehirleri atacağız. Bunu elle yapmayacağız, bir json dosyasından çekip listeye aktaracağız. Gerekli json dosyasına buradan ulaşabilirsiniz.
Bu json dosyasını indirdikten sonra flutter projemizin içine attık. Lib'in altında assets klasörü oluşturup onun içine atabilirsiniz. Bu json dosyasını asset olarak tanıtabilmemiz için pubspec.yaml dosyasının içine
assets:
- lib/assets/cities.json
ekliyoruz. Json dosyamızı tanıttıktan sonra sıra modelimizi oluşturmaya geldi.
class WeatherModel{ | |
String city=""; | |
String cityStatus=""; | |
String cityWeather=""; | |
WeatherModel({required this.city, required this.cityStatus, required this.cityWeather }); | |
factory WeatherModel.fromJson(Map<String, dynamic> json) { | |
return WeatherModel( | |
city: json['name'], | |
cityStatus: json['weather'][0]['description'], | |
cityWeather: json['main']['temp'].toString(), | |
); | |
} | |
} |
Modelimiz bu şekilde. Api'dan şehir ismi, sıcaklık değeri ve açıklamasını alacağımız için modelde 3 alan oluşturdum. Sıra servis dosyasını yazmaya geldi.
import 'dart:convert'; | |
import 'package:flutter/services.dart'; | |
import 'package:http/http.dart' as http; | |
import '../models/models.dart'; | |
class ApiServices{ | |
Future<WeatherModel> makeList({city}) | |
async { | |
final url = Uri.parse('https://api.openweathermap.org/data/2.5/weather?q='+city+'&lang=tr&units=metric&appid=...'); | |
final response = await http.get(url); | |
if (response.statusCode == 200) { | |
return WeatherModel.fromJson(json.decode(response.body)); | |
} else { | |
throw Exception('Failed to load post'); | |
} | |
} | |
readJson() async { | |
var response = await rootBundle.loadString('lib/assets/cities.json'); | |
Map<String, dynamic> map = await json.decode(response); | |
return map["cities"]; | |
} | |
} |
Bu dosyada ise Api'a istek atıyoruz. İstek attığımız url "https://api.openweathermap.org/data/2.5/weather?q='+city+'&lang=tr&units=metric&appid=..."
Url'in sonunda gördüğünüz "appid=..." kısmı sizin bu siteye girip kaydolduğunuzda aldığınız bir anahtarı koyacağınız kısım. Yani OpenWeather sistemine kaydolacaksınız, size bir app id verilecek, siz de istek url'inin sonuna "appid=" şeklinde koyacaksınız. Böylece api'a erişim sağlamış olacaksınız.
Servis dosyasında gördüğünüz readJson adındaki fonksiyon ile cities.json dosyasını okuyoruz. Json dosyasını okuduktan sonra geriye dönen cevabı bir map'e atıyoruz. Sonra map'in "cities" indeksli kısmını return ediyoruz.
Main.dart dosyamız şu şekilde;
import 'package:flutter/material.dart'; | |
import 'package:weather_app/services/services.dart'; | |
import 'models/models.dart'; | |
void main() { | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({Key? key}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
debugShowCheckedModeBanner: false, | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: const MyHomePage(), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
const MyHomePage({Key? key}) : super(key: key); | |
@override | |
State<MyHomePage> createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
Color topColor=Colors.redAccent; | |
Color bottomColor= Colors.deepPurpleAccent; | |
ApiServices apiObj = new ApiServices(); | |
late Future<WeatherModel> weatherInf; | |
Map<String, dynamic> map = new Map(); | |
List<String> cityList=[]; | |
String cityName=""; | |
cityListSet() | |
async { | |
var tempList = await apiObj.readJson(); | |
for(int i=0; i<tempList.length;i++) | |
{ | |
cityList.add(tempList[i]["name"]); | |
} | |
setState(() { | |
}); | |
} | |
getWeather(String city) | |
{ | |
setState(() { | |
weatherInf = apiObj.makeList(city: city); | |
}); | |
} | |
getIcon(String weatherStatus) | |
{ | |
if(weatherStatus == "açık") | |
{ | |
topColor=Colors.deepOrangeAccent; | |
bottomColor= Colors.yellowAccent; | |
return Container( | |
child: Text("☀️", style: TextStyle(fontSize: 50),), | |
); | |
} | |
else if(weatherStatus == "parçalı bulutlu" || weatherStatus == "parçalı az bulutlu" || weatherStatus == "az bulutlu") | |
{ | |
topColor=Colors.blue; | |
bottomColor= Colors.lightBlueAccent; | |
return Container( | |
child: Text("☁️", style: TextStyle(fontSize: 50)), | |
); | |
} | |
else if(weatherStatus == "kapalı") | |
{ | |
topColor=Colors.white38; | |
bottomColor= Colors.white10; | |
return Container( | |
child: Text("🌫️", style: TextStyle(fontSize: 50)), | |
); | |
} | |
else if(weatherStatus == "sisli") | |
{ | |
topColor=Colors.white10; | |
bottomColor= Colors.brown; | |
return Container( | |
child: Text("🌁", style: TextStyle(fontSize: 50)), | |
); | |
} | |
else | |
{ | |
return Container( | |
child: Text("❔", style: TextStyle(fontSize: 50)), | |
); | |
} | |
} | |
initState() { | |
cityListSet(); | |
getWeather("edirne"); | |
super.initState(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
backgroundColor: Colors.redAccent, | |
title: Text("WEATHER APP", style: TextStyle( | |
color: Colors.deepPurple, | |
fontSize: 30 | |
),), | |
centerTitle: true, | |
toolbarHeight: 100, | |
), | |
body: SingleChildScrollView( | |
child: Container( | |
width: MediaQuery.of(context).size.width, | |
height: MediaQuery.of(context).size.height*0.85, | |
child: FutureBuilder<WeatherModel>( | |
future: weatherInf, | |
builder: (context, snapshot) { | |
if (snapshot.hasData) { | |
return Container( | |
child: Column( | |
children: [ | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Container( | |
margin: EdgeInsets.fromLTRB(0, 20, 0, 0), | |
child: Text("🏙️ Şehir seçiniz:", style: TextStyle(fontSize: 30, color: Colors.black),), | |
) | |
], | |
), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Container(width: 200, height: 30, color:Colors.white,margin: EdgeInsets.fromLTRB(0, 20, 0, 0), | |
child: Autocomplete<String>( | |
onSelected: (String option) | |
{ | |
getWeather(cityName); | |
}, | |
optionsBuilder: (TextEditingValue textEditingValue) { | |
cityName=textEditingValue.text; | |
if (textEditingValue.text == '') { | |
return const Iterable<String>.empty(); | |
} | |
return cityList.where((String option) { | |
return option.contains(textEditingValue.text.toLowerCase()); | |
}); | |
}, | |
),), | |
], | |
), | |
Container( | |
margin: EdgeInsets.fromLTRB(0, 50, 0, 0), | |
child: Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
crossAxisAlignment: CrossAxisAlignment.center, | |
children: [ | |
Container( margin: EdgeInsets.fromLTRB(0, 10, 0, 0),child: Text(snapshot.data?.city ?? "BOŞ", style: TextStyle(color: Colors.black, fontSize: 25),)), | |
getIcon(snapshot.data?.cityStatus ?? "BOŞ"), | |
], | |
), | |
), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Container(margin: EdgeInsets.fromLTRB(0, 5, 0, 0),child: Text(snapshot.data?.cityWeather.toString() ?? "0.0", style: TextStyle(color: Colors.black, fontSize: 50))) | |
], | |
) | |
], | |
), | |
decoration: BoxDecoration( | |
gradient: LinearGradient( | |
begin: Alignment.topCenter, | |
end: Alignment.bottomCenter, | |
colors: [topColor, bottomColor]) | |
), | |
); | |
} else if (snapshot.hasError) { | |
return Text("${snapshot.error}"); | |
} | |
return Container(child: Center(child: Text("Bilgi geliyor...", style: TextStyle(fontSize: 24),))); | |
} | |
), | |
), | |
), | |
); | |
} | |
} |
Modelimizi ve servisimizi import etmeyi unutmuyoruz;
import 'package:flutter/material.dart';import 'package:weather_app/services/services.dart';
cityListSet();
getWeather("edirne");
super.initState();
}
Uygulamamızın ilk yüklenişinde çalışan fonksiyonumuza cityListSet ve getWeather fonksiyonlarını yazdım. Sebebi, ekran çizilirken cities.json dosyasından şehirleri hemen çekip listeye atması ve uygulama ilk açıldığında istediğim şehri parametre olarak göndererek hava durumunu api'dan istemesidir.
{
setState(() {
weatherInf = apiObj.makeList(city: city);
});
}
async {
var tempList = await apiObj.readJson();
for(int i=0; i<tempList.length;i++)
{
cityList.add(tempList[i]["name"]);
}
setState(() {
});
}
onSelected: (String option)
{
getWeather(cityName);
},
optionsBuilder: (TextEditingValue textEditingValue) {
cityName=textEditingValue.text;
if (textEditingValue.text == '') {
return const Iterable<String>.empty();
}
return cityList.where((String option) {
return option.contains(textEditingValue.text.toLowerCase());
});
},
)
Yorumlar
Yorum Gönder