A weather forecasting application built with Flutter, following Clean Architecture principles with a feature-based folder structure. The app features a modern blurry UI theme and offers functionalities like current weather, 5-day forecasts, and city bookmarking. This project integrates with the OpenWeatherMap API for weather data and uses the GeoDB Cities API for city selection.
Important
The purpose of this code is to implement Clean Architecture in the program. You may notice bugs in the UI. If so, please submit an issue or a pull request.
- Current Weather Data: Fetch weather updates.
- 5-Day Forecast: View detailed weather forecasts for the next five days.
- City Bookmarking: Save your favorite cities for quick access to weather updates.
- Blurry UI Design: Enjoy a visually appealing, modern interface.
- Feature-Based Clean Architecture: Organized code structure to separate concerns and enhance maintainability.
- Comprehensive Testing: Includes unit tests, bloc tests, and UI tests.
Ensure you have the following installed:
This app requires an API key from OpenWeatherMap to fetch weather data. Follow the steps below to obtain and configure your API key:
-
Get an API Key from OpenWeatherMap:
- Visit the OpenWeatherMap website and create an account if you don't have one.
- After signing up, log in to your account.
- Navigate to the API keys section in your profile.
- Generate a new API key and copy it.
-
Add the API Key to the Project:
- Open the file located at
lib/core/utils/constants.dart
. - Locate the
apiKey1
variable and replace its value with your OpenWeatherMap API key. It should look like this:
class Constants { static const baseUrl = 'https://api.openweathermap.org'; static const apiKey1 = 'YOUR_API_KEY_HERE'; // Add your API_KEY here }
- Replace
'YOUR_API_KEY_HERE'
with the actual API key you obtained from OpenWeatherMap.
- Open the file located at
-
Clone the repository:
git clone https://github.com/omidhaqi/weather_app.git
-
Navigate to the project directory:
cd weather_app
-
Install dependencies:
flutter pub get
To run the app on a connected device or emulator, use:
flutter run
To run all the tests, use:
flutter test
To run tests with coverage:
flutter test --coverage
To run a specific test file:
flutter test test/<test_file_name>.dart
To generate a code coverage report:
-
Run tests with coverage:
flutter test --coverage
-
Generate and view the coverage report:
genhtml coverage/lcov.info -o coverage/html
-
Open
coverage/html/index.html
in your browser to view the detailed report.
This project follows a feature-based Clean Architecture structure. Each feature is organized into its own folder with separate layers for data, domain, and presentation:
lib
├── core
│ ├── params
│ │ └── forecast_params.dart
│ ├── resources
│ │ └── date_state.dart
│ ├── use_case
│ │ └── use_case.dart
│ ├── utils
│ │ ├── constants.dart
│ │ ├── date_converter.dart
│ │ └── themes.dart
│ └── widgets
│ ├── app_background.dart
│ ├── bottom_nav.dart
│ ├── dot_loading_widget.dart
│ └── main_wrapper.dart
├── features
│ ├── feature_bookmark
│ │ ├── data
│ │ │ ├── date_source
│ │ │ │ └── local
│ │ │ │ ├── city_dao.dart
│ │ │ │ ├── database.dart
│ │ │ │ └── database.g.dart
│ │ │ └── repository
│ │ │ └── city_repositoryimpl.dart
│ │ ├── domain
│ │ │ ├── entities
│ │ │ │ └── city_entity.dart
│ │ │ ├── repository
│ │ │ │ └── city_repository.dart
│ │ │ └── use_cases
│ │ │ ├── delete_city_usecase.dart
│ │ │ ├── get_all_city_usecase.dart
│ │ │ ├── get_city_usecase.dart
│ │ │ └── save_city_usecase.dart
│ │ └── presentation
│ │ ├── bloc
│ │ │ ├── bookmark_bloc.dart
│ │ │ ├── bookmark_event.dart
│ │ │ ├── bookmark_state.dart
│ │ │ ├── delete_city_status.dart
│ │ │ ├── get_all_city_status.dart
│ │ │ ├── get_city_status.dart
│ │ │ └── save_city_status.dart
│ │ ├── screens
│ │ │ └── bookmark_screen.dart
│ │ └── widgets
│ └── feature_weather
│ ├── data
│ │ ├── date_sorurce
│ │ │ └── remote
│ │ │ └── api_provider.dart
│ │ ├── model
│ │ │ ├── current_city_model.dart
│ │ │ ├── forecast_days_model.dart
│ │ │ └── suggest_city_model.dart
│ │ └── repository
│ │ └── weather_repository_impl.dart
│ ├── domain
│ │ ├── entities
│ │ │ ├── current_city_entity.dart
│ │ │ ├── forecase_days_entity.dart
│ │ │ └── suggest_city_entity.dart
│ │ ├── repository
│ │ │ └── weather_repository.dart
│ │ └── use_cases
│ │ ├── get_current_weather_usecase.dart
│ │ ├── get_forecast_weather_usecase.dart
│ │ └── get_suggestion_city_usecase.dart
│ └── presentation
│ ├── bloc
│ │ ├── cw_status.dart
│ │ ├── fw_status.dart
│ │ ├── home_bloc.dart
│ │ ├── home_event.dart
│ │ └── home_state.dart
│ ├── screens
│ │ └── home_screen.dart
│ └── widgets
│ ├── bookmark_icon.dart
│ ├── city_search.dart
│ └── day_weather_view.dart
├── locator.dart
└── main.dart
36 directories, 52 files
- The Data Layer of the
feature_bookmark
module uses Floor and SQLite for local data persistence. - Floor serves as an abstraction layer over SQLite, simplifying database interactions.
- The repository implementation in
feature_bookmark/data/repository/city_repositoryimpl.dart
interacts with Floor DAOs and SQLite directly to manage local city data.
- bloc - State management.
- flutter_bloc - Flutter widgets that integrate with Bloc.
- dio - Networking library.
- sqflite - Local database.
- floor - Database abstraction layer.
- equatable - Simplifies equality comparisons.
- flutter_typeahead - Autocomplete text field.
- get_it - Dependency injection.
- intl - Internationalization and localization.
- loading_animation_widget - Loading animations.
- smooth_page_indicator - Page indicators.
- blurbox - Blurry UI components.
- mockito - Mocking library for tests.
- bloc_test - Testing library for Bloc.
- lints - Official Dart linter rules.
- OpenWeatherMap API - For weather data.
- GeoDB Cities API - For city search.
This project is licensed under the Apache License - see the LICENSE file for details.
Version 0.0.1+1
Developed with ☕ by Umut