Create an Android app that displays the weather forecast.
- Display the weather forecast for the current day.
- Display the weather forecast for the week.
- Display the weather forecast for the current city.
- Allow the user to choose any other city and view its weather forecast.
- The solution must contain at least one feature module.
The developed app is called F☀️recast. The following sections detail its features, design decisions, tech stack, architecture, and development tools used.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
- Display the current weather forecast for the user's location (Requirements: 1, 2)
- Search for cities and display their current weather forecast (Requirements: 3, 4)
- Select a city or location and view the weekly weather forecast (Requirement 2)
- Switch between Celsius and Fahrenheit temperature units
- Material 3 design system
- "Warm Coastal" app theme
- Light mode ("midday sun on warm sand") and dark mode ("beach fire at night")
- Temperature-reactive color scheme — the UI adapts its colors to reflect the current temperature
| Category | Library |
|---|---|
| Language | Kotlin |
| UI | Jetpack Compose, Material 3 |
| Navigation | Jetpack Navigation Compose |
| Dependency Injection | Hilt |
| Concurrency | Coroutines, Flow |
| Networking | Ktor |
| Serialization | Kotlin Serialization |
| Lifecycle | AndroidX Lifecycle, ViewModel |
| Collections | KotlinX Immutable Collections |
| Logging | Timber |
| Testing | JUnit |
| Weather Data | Open Meteo — open source, free for non-commercial use, no API key required |
| Geocoding | Nominatim — open source, free for non-commercial use, no API key required |
The app follows Clean Architecture principles, with modules organized into three horizontal layers — presentation, domain, and data. The domain layer sits between presentation and data, and dependencies always point inward toward the domain.
| Module | Description |
|---|---|
:app |
Entry point — assembles modules and wires navigation |
:common |
Shared utilities across all layers |
:domain |
Highest level module — contains business logic and use cases, no dependencies on other modules |
:domain:dataapi |
Contracts (interfaces) between the data layer and domain layer |
:domain:presentationapi |
Contracts (interfaces) between the domain layer and presentation layer |
:data:weather |
Data layer — retrieves weather forecasts for coordinates |
:data:geocoding |
Data layer — retrieves geographic coordinates from search strings |
:data:location |
Data layer — retrieves the device's geographic coordinates |
:data:common |
Shared data layer utilities |
:ui:common |
Shared UI theme and components across the presentation layer |
:feature:cityforecast |
Feature module in the presentation layer — city list and detail screens (Requirement 5) |
This feature module delivers the features listed above — displaying weather forecasts for cities, using an MVVM architecture with unidirectional data flow.
The public interface is intentionally minimal. The feature registers its screens via a NavGraphBuilder extension:
fun NavGraphBuilder.cityForecastNavGraph(appContainerState: AppContainerState)Call this within a NavHost block (in AppContainerNavHost in :app) to add the city list and detail screens to the navigation graph.
- Project was bootstrapped from my existing repo RickAndMortyInterviewCoding and developed from there
- Material Theme Builder — inspiration for the app's color scheme
- Image Asset Studio (built into Android Studio) — generated the launch icon from a source image
- Claude — used as a development assistant throughout the project:
- Recommended the free APIs used for weather data and geocoding
- Jetpack Compose patterns and best practices
- Architecture decisions and code review
- Generating unit tests
- App icon image generation
- Theme design and color system
- The
:data:locationmodule and location permission UI were fully generated by Claude Code — boilerplate I had no interest in writing by hand. The only manual change was converting the location service from a suspend function to a Flow.
Note
All code was reviewed, understood, and integrated by the author.






