Weather forecast feature built on top of an existing Android multi-module project.
Implement a weather screen that shows current conditions and a forecast for a user-selected city. The city is persisted between sessions so the app reopens on the last chosen location. A city search screen allows switching to any location via geocoding.
Weather Screen
- Current weather: temperature, feels-like, condition, humidity, wind speed
- Hourly forecast for today
- 7-day daily forecast
- Button to open city search
City Search Screen (bottom sheet)
- Real-time search with 400 ms debounce (min 2 characters)
- Results from OpenWeatherMap Geocoding API
- Selected city saved to SharedPreferences
| Endpoint | Usage |
|---|---|
GET data/2.5/weather |
Current weather by city name |
GET data/2.5/forecast |
5-day / 3-hour forecast |
GET geo/1.0/direct |
City search (geocoding) |
| Area | Library / Approach |
|---|---|
| UI | Jetpack Compose + Material 3 |
| Architecture | MVVM — BaseViewModel<State, Event, Effect> |
| State | MutableStateFlow + collectAsStateWithLifecycle |
| DI | Hilt (@HiltViewModel, constructor injection) |
| Networking | Retrofit 3 + OkHttp 5 + Kotlinx Serialization |
| Navigation | Custom Navigator abstraction (no direct NavController in VMs) |
| Image loading | Coil |
| Logging | Timber |
| Build | KSP, Compose Compiler plugin, version catalog (libs.versions.toml) |
The project follows a multi-module MVVM structure:
feature/weather/
├── api/ # Public contracts: WeatherRepository interface, domain + UI models
└── src/ # Implementation: API services, repository, DI, screens, ViewModels
Data flows one way: ViewModel → Repository → Retrofit API / SharedPreferences → DTOs → Domain Mappers → UI Models → Compose UI.
Navigation is decoupled from screens via a custom Navigator interface — ViewModels never hold a NavController reference.