Skip to content

About

🌀️ WeatherWise – A Flutter-powered personal weather dashboard with real-time data, favorite cities, and Celsius/Fahrenheit toggle. Built with Provider for efficient state management and clean Material 3 UI.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

Β 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌀️ WeatherWise

A Personal Weather Dashboard built with Flutter & Provider
Real-time weather data Β· Favorites management Β· Celsius / Fahrenheit toggle


πŸ“‘ Table of Contents

  1. Features
  2. Architecture & Approach
  3. Folder Structure
  4. Prerequisites
  5. Getting the API Key
  6. Clone & Run
  7. State Management – Provider
  8. Key Design Decisions
  9. Dependencies
  10. Author

✨ Features

Feature Description
πŸ™οΈ Major Cities Horizontally scrollable cards for 8 pre-defined global cities
❀️ Favourites Add / remove cities; persisted in app state via Provider
πŸ” Search Search any city worldwide with loading, error, and success states
🌑️ Unit Toggle Switch between Celsius and Fahrenheit globally from Settings
πŸ”„ Pull-to-Refresh Swipe down on Home to re-fetch all city data
πŸ“± Material 3 UI Clean gradient AppBar, cards, bottom nav, and consistent theming

πŸ—οΈ Architecture & Approach

The project follows a feature-first folder layout with a clean separation of concerns:

Presentation (UI)  ←──  Provider (State)  ←──  Service (Network)  ←──  OpenWeatherMap API
  • Model (weather_model.dart) – pure Dart; parses JSON from OpenWeatherMap.
  • Service (weather_service.dart) – responsible only for HTTP calls.
  • Provider (weather_provider.dart) – holds all app state, exposes methods, calls notifyListeners().
  • Screens / Widgets – consume Provider via Consumer<WeatherProvider>; zero business logic lives here.

Why Provider?

Provider is the officially recommended lightweight state management solution for Flutter. It uses InheritedWidget under the hood, which means:

  • No boilerplate (unlike BLoC/Redux).
  • Widget rebuilds are surgical – only Consumer subtrees re-render.
  • Easy to unit-test (just inject a mock provider).

πŸ“‚ Folder Structure

lib/
β”œβ”€β”€ main.dart                            # App entry-point, ChangeNotifierProvider setup
β”‚
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ constants/
β”‚   β”‚   β”œβ”€β”€ api_openweathermap.dart      # Base URL & key reference
β”‚   β”‚   β”œβ”€β”€ secrets.dart                # ⚠️  GITIGNORED – your real API key goes here
β”‚   β”‚   └── secrets.dart.example        # Template – copy β†’ secrets.dart
β”‚   └── utils/                          # (helper utilities, extendable)
β”‚
└── features/
    └── weather/
        β”œβ”€β”€ data/
        β”‚   β”œβ”€β”€ weather_service.dart     # HTTP layer (http package)
        β”‚   └── weather_provider.dart   # ChangeNotifier – all app state
        β”‚
        β”œβ”€β”€ domain/
        β”‚   └── weather_model.dart      # Weather data model + fromJson factory
        β”‚
        └── ui/
            β”œβ”€β”€ screens/
            β”‚   β”œβ”€β”€ home_screen.dart     # Major cities + favourites
            β”‚   β”œβ”€β”€ search_screen.dart   # City search + result display
            β”‚   └── settings_screen.dart # Unit toggle (Β°C / Β°F)
            └── widgets/
                β”œβ”€β”€ city_weather_card.dart    # Horizontal city card
                └── favorite_city_tile.dart   # Favourite list tile

πŸ› οΈ Prerequisites

Tool Minimum Version Check command
Flutter SDK 3.10.0 flutter --version
Dart SDK 3.0.0 dart --version
Android Studio / VS Code Latest β€”
Android emulator or physical device API 21+ flutter devices

β†’ Install Flutter: https://docs.flutter.dev/get-started/install


πŸ”‘ Getting the API Key

WeatherWise uses the free tier of OpenWeatherMap.

Step-by-step

  1. Sign up at https://openweathermap.org/ β€” click Sign In β†’ Create an Account.
  2. Confirm your email address by clicking the link in the verification email.
  3. Log in and go to your dashboard.
  4. Click your username (top-right) β†’ My API keys.
  5. Copy the Default key that is already generated, or click Generate to create a new named key.

⚠️ New keys can take up to 2 hours to activate.
The API will return 401 Invalid API key until then β€” this is completely normal.

Adding the key to the project

# 1. Copy the example template
cp lib/core/constants/secrets.dart.example lib/core/constants/secrets.dart

# 2. Open secrets.dart and replace the placeholder:
#       static const String openWeatherMapApiKey = 'YOUR_API_KEY_HERE';
#    with your real key, e.g.:
#       static const String openWeatherMapApiKey = 'abc123def456...';

secrets.dart is listed in .gitignore β€” it will never be committed accidentally.


πŸš€ Clone & Run

# 1. Clone the repository
git clone https://github.com/<your-username>/WeatherWise-Flutter.git
cd WeatherWise-Flutter

# 2. Set up your API key (see section above)
cp lib/core/constants/secrets.dart.example lib/core/constants/secrets.dart
# β†’ Edit secrets.dart and paste your OpenWeatherMap key

# 3. Install Flutter dependencies
flutter pub get

# 4. Verify no issues
flutter analyze

# 5. Run the app (debug mode)
flutter run

# ── Optional commands ────────────────────────────────────────────────────────

# List connected devices
flutter devices

# Run on a specific device
flutter run -d <device_id>

# Build a release APK
flutter build apk --release

# Build a release App Bundle (for Play Store)
flutter build appbundle --release

🧠 State Management – Provider

How it is wired up

// main.dart
ChangeNotifierProvider(
  create: (_) => WeatherProvider(),
  child: MaterialApp( ... ),
)

Listening to state changes (rebuilds UI)

Consumer<WeatherProvider>(
  builder: (context, provider, child) {
    return Text(provider.formatTemperature(weather.temperature));
  },
)

One-off read (no rebuild)

final provider = Provider.of<WeatherProvider>(context, listen: false);
provider.fetchWeather('London');

Provider state fields

Field Type Purpose
_cityWeatherData Map<String, Weather> Cache of fetched weather keyed by lowercase city name
_favoriteCities List<String> User-selected favourite city names
_isCelsius bool Current unit preference (true = Β°C)
_isLoading bool Drives CircularProgressIndicator in UI
_errorMessage String? Displayed as red error text in UI
_searchedWeather Weather? Latest Search screen result

Key provider methods

Method Description
fetchWeather(city) Calls API, caches result, updates search result, notifies UI
fetchAllPredefinedCities() Bulk-fetches all Home screen cities on first load
refreshAllWeather() Re-fetches all cached cities (used after unit toggle)
toggleUnit(isCelsius) Switches Β°C/Β°F and triggers refreshAllWeather()
addToFavorites(city) Appends city to favourites list
removeFromFavorites(city) Removes city from favourites list
isFavorite(city) Returns bool – used to disable "Add to Favourites" button
getFavoriteWeathers() Returns List<Weather> for all favourite cities
formatTemperature(temp) Returns e.g. "25Β°C" or "77Β°F" based on current setting
clearSearch() Resets search result (called when Search screen opens)

πŸ’‘ Key Design Decisions

1. Secrets management

API keys are never hard-coded in source. They live in secrets.dart (excluded by .gitignore). A secrets.dart.example serves as a safe, committed template for all contributors.

2. Case-insensitive city cache

All cache look-ups use cityName.toLowerCase(), so "london" and "London" always resolve to the same cached entry.

3. Unit switching triggers re-fetch

When the user toggles Β°C ↔ Β°F, refreshAllWeather() is invoked automatically. OpenWeatherMap returns values already in the chosen unit (metric / imperial), so no client-side conversion math is required.

4. Error handling

Scenario Behaviour
City not found (404) User-friendly "City not found" message
Network failure "Check your internet connection" message
Empty search SnackBar warning, no API call made
Icon load failure Icons.cloud fallback widget

5. Pull-to-refresh

RefreshIndicator wraps the Home ListView so users can swipe-down to reload all city data at any time.

6. Navigation pattern

  • Home β†’ Search and Home β†’ Settings use Navigator.push(MaterialPageRoute(...)).
  • The back arrow and device back button automatically call Navigator.pop(), returning to Home.
  • Provider state persists across navigation because the ChangeNotifierProvider sits above MaterialApp.

πŸ“¦ Dependencies

Package Version Purpose
flutter SDK UI framework
provider ^6.1.2 State management (ChangeNotifier)
http ^1.2.0 HTTP GET requests to OpenWeatherMap
cupertino_icons ^1.0.8 iOS-style icon assets

πŸ‘€ Author

Muhammad Hunain
Roll Number: 22K-5037
BS Software Engineering

Assignment 1 – Smart Mobile Development
WeatherWise – Personal Weather Dashboard


πŸ“„ License

This project is open-source and available under the MIT License.


Made with ❀️ and Flutter

About

🌀️ WeatherWise – A Flutter-powered personal weather dashboard with real-time data, favorite cities, and Celsius/Fahrenheit toggle. Built with Provider for efficient state management and clean Material 3 UI.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages