Flutter Functions

 

Building a Weather App with Flutter: API Integration and UI Design

Weather apps have become an integral part of our daily lives, helping us plan our activities and stay prepared for the elements. If you’re an aspiring mobile app developer looking to enhance your skills with Flutter, building a weather app is an excellent project to undertake. In this tutorial, we’ll guide you through the process of creating a weather app with Flutter, complete with API integration for real-time weather data and a beautifully designed user interface.

Building a Weather App with Flutter: API Integration and UI Design

1. Prerequisites

Before we dive into the development process, make sure you have the following prerequisites in place:

1.1. Flutter Installed

Ensure that you have Flutter and Dart installed on your system. You can follow the official Flutter installation guide for your specific operating system: Flutter Installation Guide.

1.2. OpenWeatherMap API Key

To fetch weather data, you’ll need an API key from OpenWeatherMap. You can sign up for a free API key at OpenWeatherMap.

1.3. Basic Flutter Knowledge

Familiarity with the basics of Flutter, such as widgets, state management, and navigation, will be helpful.

Now that you have all the prerequisites covered, let’s get started on building your weather app.

Step 1: Project Setup

Begin by creating a new Flutter project using the following command:

bash
flutter create weather_app
cd weather_app

Replace weather_app with your preferred project name.

Step 2: Dependencies

In your pubspec.yaml file, add the necessary dependencies for this project:

yaml
dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.3 # For making HTTP requests
  provider: ^5.0.3 # For state management
  flutter_svg: ^0.24.0 # For SVG support

Save the file, and run flutter pub get to fetch the packages.

Step 3: Create Models

Create two Dart files, weather_data.dart and location_data.dart, to define the data models for weather information and location details, respectively.

dart
// weather_data.dart
class WeatherData {
  final String city;
  final String description;
  final double temperature;
  final int humidity;
  final String iconCode;

  WeatherData({
    required this.city,
    required this.description,
    required this.temperature,
    required this.humidity,
    required this.iconCode,
  });
}

// location_data.dart
class LocationData {
  final double latitude;
  final double longitude;

  LocationData({
    required this.latitude,
    required this.longitude,
  });
}

Step 4: API Integration

We’ll use the http package to make API requests to OpenWeatherMap. Create a weather_api.dart file to handle the API calls:

dart
import 'dart:convert';
import 'package:http/http.dart' as http;

class WeatherApi {
  final String apiKey;
  final String apiUrl = 'https://api.openweathermap.org/data/2.5/weather';

  WeatherApi({required this.apiKey});

  Future<Map<String, dynamic>> fetchWeatherData(double latitude, double longitude) async {
    final response = await http.get('$apiUrl?lat=$latitude&lon=$longitude&appid=$apiKey&units=metric');
    
    if (response.statusCode == 200) {
      return json.decode(response.body);
    } else {
      throw Exception('Failed to load weather data');
    }
  }
}

Make sure to replace ‘YOUR_API_KEY’ with your actual OpenWeatherMap API key.

Step 5: Implement State Management

For state management, we’ll use the provider package. Create a weather_provider.dart file to manage the weather data.

dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:your_project_name/location_data.dart';
import 'package:your_project_name/weather_data.dart';
import 'package:your_project_name/weather_api.dart';

class WeatherProvider with ChangeNotifier {
  WeatherData? _weatherData;
  LocationData? _locationData;

  WeatherProvider() {
    _locationData = LocationData(latitude: 0.0, longitude: 0.0); // Initialize with default location
    fetchWeatherData();
  }

  WeatherData? get weatherData => _weatherData;
  LocationData? get locationData => _locationData;

  void setLocation(double latitude, double longitude) {
    _locationData = LocationData(latitude: latitude, longitude: longitude);
    fetchWeatherData();
  }

  Future<void> fetchWeatherData() async {
    try {
      final api = WeatherApi(apiKey: 'YOUR_API_KEY');
      final data = await api.fetchWeatherData(_locationData!.latitude, _locationData!.longitude);
      _weatherData = WeatherData(
        city: data['name'],
        description: data['weather'][0]['description'],
        temperature: data['main']['temp'],
        humidity: data['main']['humidity'],
        iconCode: data['weather'][0]['icon'],
      );
      notifyListeners();
    } catch (e) {
      print('Error fetching weather data: $e');
    }
  }
}

Replace ‘YOUR_API_KEY’ with your actual OpenWeatherMap API key.

Step 6: UI Design

Now, let’s create the user interface for your weather app. We’ll design a simple yet attractive interface using Flutter’s widgets and the flutter_svg package for displaying weather icons.

Home Screen

Create a home_screen.dart file for the home screen of your weather app:

dart
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
import 'package:your_project_name/weather_data.dart';
import 'package:your_project_name/weather_provider.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final weatherData = Provider.of<WeatherProvider>(context).weatherData;

    return Scaffold(
      appBar: AppBar(
        title: Text('Weather App'),
      ),
      body: Center(
        child: weatherData != null
            ? WeatherInfoWidget(weatherData: weatherData)
            : CircularProgressIndicator(),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // Open a location picker screen or use device location services
        },
        child: Icon(Icons.location_on),
      ),
    );
  }
}

class WeatherInfoWidget extends StatelessWidget {
  final WeatherData weatherData;

  WeatherInfoWidget({required this.weatherData});

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        SvgPicture.asset('assets/weather_icons/${weatherData.iconCode}.svg', width: 100),
        SizedBox(height: 16),
        Text(weatherData.city, style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
        Text(weatherData.description, style: TextStyle(fontSize: 16)),
        SizedBox(height: 16),
        Text('${weatherData.temperature.toStringAsFixed(1)}°C', style: TextStyle(fontSize: 32)),
        Text('Humidity: ${weatherData.humidity}%', style: TextStyle(fontSize: 16)),
      ],
    );
  }
}

In this code, we use the SvgPicture.asset widget to display weather icons. Make sure you have weather icons in SVG format in an assets/weather_icons folder.

Location Picker Screen

Create a location_picker_screen.dart file for the location picker screen, where users can choose a location or use device location services:

dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:your_project_name/location_data.dart';
import 'package:your_project_name/weather_provider.dart';

class LocationPickerScreen extends StatefulWidget {
  @override
  _LocationPickerScreenState createState() => _LocationPickerScreenState();
}

class _LocationPickerScreenState extends State<LocationPickerScreen> {
  double _latitude = 0.0;
  double _longitude = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Choose Location'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Latitude: $_latitude'),
            Text('Longitude: $_longitude'),
            ElevatedButton(
              onPressed: () {
                // Implement location picker logic here
                // Update _latitude and _longitude accordingly
                final weatherProvider = Provider.of<WeatherProvider>(context, listen: false);
                weatherProvider.setLocation(_latitude, _longitude);
                Navigator.pop(context);
              },
              child: Text('Set Location'),
            ),
          ],
        ),
      ),
    );
  }
}

This screen allows users to set a custom location by providing latitude and longitude coordinates.

Step 7: Navigation

Configure navigation within your app by creating a routes.dart file:

dart
import 'package:flutter/material.dart';
import 'package:your_project_name/home_screen.dart';
import 'package:your_project_name/location_picker_screen.dart';

final Map<String, WidgetBuilder> routes = {
  '/': (context) => HomeScreen(),
  '/location_picker': (context) => LocationPickerScreen(),
};

Step 8: Main Function

Update the main.dart file to include the necessary configurations and start the app:

dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:your_project_name/routes.dart';
import 'package:your_project_name/weather_provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => WeatherProvider(),
      child: MaterialApp(
        title: 'Weather App',
        theme: ThemeData(primarySwatch: Colors.blue),
        initialRoute: '/',
        routes: routes,
      ),
    );
  }
}

Step 9: Running the App

You can now run your weather app using the following command:

bash
flutter run

Open the app on your emulator or physical device, and you’ll see your beautiful weather app in action. You can navigate to the location picker screen by tapping the floating action button and set a custom location.

Congratulations! You’ve successfully built a weather app with Flutter that integrates real-time weather data and boasts an attractive user interface.

Conclusion

In this tutorial, we walked through the process of building a weather app with Flutter, focusing on API integration and UI design. You’ve learned how to set up your project, fetch weather data from OpenWeatherMap, manage app state using the provider package, and create a user-friendly interface. This project not only enhances your Flutter skills but also gives you a real-world application to showcase in your portfolio. Happy coding!

Previously at
Flag Argentina
Brazil
time icon
GMT-3
Full Stack Systems Analyst with a strong focus on Flutter development. Over 5 years of expertise in Flutter, creating mobile applications with a user-centric approach.