Horizon is a simple weather app built completely with Jetpack Compose. Under the hood, it uses the Open-Meteo Weather API to fetch the data. It also uses Google's Gemini client SDK to display a short, whimsical summary of the current weather of a particular location. This app uses the Material 3 design system and also supports dynamic colors on supported devices.
- Demo
- Screenshots
- Tech Stack
- Remote API's
- Notable Features
- Source code, Architecture, & Testing
- Building and running the app
Horizon_Working.mp4
- Entirely written in Kotlin.
- Hilt for dependency injection.
- Jetpack Compose for UI and navigation.
- Coil compose for image loading and caching.
- Coil-gif for loading and displaying gif's.
- Coil-svg for loading and displaying svg's from URL's.
- SplashScreen API for displaying a splashscreen in a backwards-compatible way.
- Kotlin Coroutines for threading.
- Kotlin Flows for creating reactive streams.
- Mokito-Kotlin for mocking dependencies in unit tests.
- Retrofit for communicating with the Open-Meteo API.
- Room for database.
- Java 8 Date/Time API for dealing with date and time.
- Timber for logging.
- Work Manager for background tasks.
- Kotlinx.Serialization for deserializing responses from the API.
- Google Play Services for getting the user’s location.
- Open-Meteo weather api for fetching weather information.
- Gemini for generating a short, whimsical summary of the current weather of a particular location.
- Adaptive UI based on permissions 🪄
- The main permission that this app needs is the location permission. The UI of the app adapts based on whether the location permission is granted or not. If it is granted, the weather for the user’s current location would be displayed directly in the Home Screen. If it is not, that portion of the UI would simply not be displayed, ensuring that the UX is not undermined even if the user chooses to not provide the location permission.
- Themed splash screen 🎨
- In Android 12 and above, the background color of the splash screen matches the system theme. This minor detail, unique to this app, helps in improving the synergy of the app with the rest of the system from the moment the app is launched.
- Error handling
⚠️ - When an error is encountered, the app ensures that it displays an appropriate error message and also provides a way to retry the operation that caused the error to occur.
- All concrete implementations are prefixed by the term “Horizon”.
- Uses multi-repository pattern.
- MVVM architecture.
- Each package is considered an individual module/submodule. Most notably, the data "module" is considered a separate module and is ensured not to depend on any other "modules" in the upper layers of the architecture.
- Commit messages follow the Conventional Commits specification.
- Consists of extensive unit tests focusing on testing the data layer.
- All api methods that use the “get” procedure under the hood have the word “get” as the prefix of the method name. All repository methods that fetch some data have the prefix “fetch” in the method's name. This way, API-specific terminologies like “get” and “post” are abstracted away from the repositories' clients.
- The app can be made to use Gemini.
for its contextual text generation features. To use, make sure to get the access / api key for the chosen LLM service,
and paste it in the
local.propertiesfile as follows. - Add the API token to the
local.propertiesfile of your project in the following manner.
GOOGLE_GEMINI_API_KEY = PASTE-YOUR-TOKEN-HERE- By default, the app uses Gemini for text generation. If you want to use Chat-GPT, then replace the '@GeminiClient'
di qualifier with the
@OpenAiClientqualifier in all places where an instance ofTextGeneratorClientis injected. - Build the project and run the app on an emulator or physical device.



