api-integration state-management weather-app flutter dart cross-platform mobile-app-development provider-package advanced-ui openweathermap
Building an Advanced Weather App with Flutter and Dart
Prerequisites
Before we start, ensure that your Flutter environment is set up. You should have Flutter and Dart installed, along with an IDE like Android Studio or Visual Studio Code.
Overview
Our weather app will:
- Fetch weather data from an external API.
- Display current temperature, weather conditions, and an icon representing the weather.
- Implement navigation between different screens.
Step 1: Setting Up the Project
Create a new Flutter project:
flutter create weather_app
Navigate to the project directory:
cd weather_app
Open the project in your preferred IDE.
Step 2: Add Dependencies
We’ll use the http
package to make network requests and provider
for state management. Update your pubspec.yaml
file to include these dependencies:
dependencies:
flutter:
sdk: flutter
http: ^0.13.3
provider: ^6.0.0
Run flutter pub get
to install the packages.
Step 3: Create the UI
Let's start by building the UI components.
Create a WeatherScreen
Widget
Create a new file lib/screens/weather_screen.dart
and add the following code:
import 'package:flutter/material.dart';
class WeatherScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Weather App'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'City Name',
style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold),
),
SizedBox(height: 16),
Text(
'25°C',
style: TextStyle(fontSize: 56),
),
SizedBox(height: 16),
Icon(
Icons.wb_sunny,
size: 100,
),
SizedBox(height: 16),
Text(
'Clear Sky',
style: TextStyle(fontSize: 24),
),
],
),
),
);
}
}
Update main.dart
Modify lib/main.dart
to load WeatherScreen
:
import 'package:flutter/material.dart';
import 'screens/weather_screen.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Weather App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: WeatherScreen(),
);
}
}
Step 4: Integrate Weather API
We will use the [OpenWeatherMap API](https://openweathermap.org/api) to fetch weather data. You’ll need to sign up and get an API key.
Create a Weather Model
Create a new file lib/models/weather.dart
and define the data model:
class Weather {
final String cityName;
final double temperature;
final String description;
final String icon;
Weather({
required this.cityName,
required this.temperature,
required this.description,
required this.icon,
});
factory Weather.fromJson(Map<String, dynamic> json) {
return Weather(
cityName: json['name'],
temperature: json['main']['temp'].toDouble(),
description: json['weather'][0]['description'],
icon: json['weather'][0]['icon'],
);
}
}
Fetch Weather Data
Create a new file lib/services/weather_service.dart
to handle API requests:
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../models/weather.dart';
class WeatherService {
final String apiKey = 'YOUR_API_KEY';
final String baseUrl = 'https://api.openweathermap.org/data/2.5/weather';
Future<Weather> fetchWeather(String city) async {
final response = await http.get(Uri.parse('$baseUrl?q=$city&appid=$apiKey&units=metric'));
if (response.statusCode == 200) {
return Weather.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load weather data');
}
}
}
Step 5: Implement State Management
We will use the provider
package to manage the app's state.
Create a Weather Provider
Create a new file lib/providers/weather_provider.dart
:
import 'package:flutter/material.dart';
import '../models/weather.dart';
import '../services/weather_service.dart';
class WeatherProvider with ChangeNotifier {
final WeatherService _weatherService = WeatherService();
Weather? _weather;
Weather? get weather => _weather;
Future<void> fetchWeather(String city) async {
_weather = await _weatherService.fetchWeather(city);
notifyListeners();
}
}
Update main.dart
Wrap the WeatherScreen
with ChangeNotifierProvider
:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'screens/weather_screen.dart';
import 'providers/weather_provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => WeatherProvider(),
child: MaterialApp(
title: 'Flutter Weather App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: WeatherScreen(),
),
);
}
}
Step 6: Connect UI with State
Update the WeatherScreen
to display real data.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/weather_provider.dart';
class WeatherScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final weatherProvider = Provider.of<WeatherProvider>(context);
return Scaffold(
appBar: AppBar(
title: Text('Weather App'),
),
body: Center(
child: weatherProvider.weather == null
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Enter City Name',
style: TextStyle(fontSize: 24),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
onSubmitted: (value) {
weatherProvider.fetchWeather(value);
},
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'City',
),
),
),
],
)
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
weatherProvider.weather!.cityName,
style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold),
),
SizedBox(height: 16),
Text(
'${weatherProvider.weather!.temperature}°C',
style: TextStyle(fontSize: 56),
),
SizedBox(height: 16),
Image.network(
'http://openweathermap.org/img/wn/${weatherProvider.weather!.icon}@2x.png',
),
SizedBox(height: 16),
Text(
weatherProvider.weather!.description,
style: TextStyle(fontSize: 24),
),
],
),
),
);
}
}
Step 7: Testing the App
Run the app using:
flutter run
Test the app by entering different city names and observing the weather data displayed.
Conclusion
In this tutorial, we built a more advanced Flutter app that fetches real-time weather data using an API and displays it with a user-friendly interface. We covered:
- Setting up an advanced UI with Flutter.
- Integrating an external API to fetch real-time data.
- Managing state with the
provider
package.
Next Steps
- Add error handling for network requests.
- Implement additional features like weather forecasts.
- Explore other state management solutions like
bloc
orriverpod
.
Comments
Please log in to leave a comment.