A modern, modular Android wallpaper app built with Jetpack Compose, Kotlin, and Clean-ish feature modularization. It lets users browse wallpaper categories, view wallpaper details, explore authors, save favourites, and customize app theme preferences.
- Overview
- Key Features
- Tech Stack
- Project Architecture
- Modules
- Screenshots
- Getting Started
- Quality and Tooling
- Notes
Banger is a multi-module Android app that integrates with the Unsplash API to serve wallpaper content. The app uses:
- A feature-first module structure (
feature/*) for UI + use cases per screen area. data:remotefor network concerns (Retrofit, OkHttp, serialization).data:localfor Room persistence and DataStore-backed settings.- Koin for dependency injection and Compose Navigation for routing.
- Browse curated wallpaper categories from Home.
- Open category-specific wallpaper feeds.
- View wallpaper details and related metadata.
- Browse authors and inspect author profile/details.
- Save and view favourite wallpapers.
- Configure app theme (system / light / dark).
- Language: Kotlin
- UI: Jetpack Compose + Material 3
- Navigation: Navigation Compose (typed routes with Kotlin serialization)
- DI: Koin
- Networking: Retrofit + OkHttp + kotlinx.serialization
- Image Loading: Coil 3
- Local Storage:
- Room (cached photos, metadata, favourites)
- DataStore Preferences (theme settings)
- Build: Gradle (Kotlin/Android plugin aliases via Version Catalog)
- Static Checks: ktlint configured at root and aggregated across modules
app (entrypoint, nav host, app scaffolding)
├── feature:home
├── feature:details
├── feature:favourites
├── feature:author
├── feature:author_details
├── feature:settings
├── shared:theme
├── shared:utility
├── data:remote
└── data:local
This project is organized by feature, where each feature commonly contains:
ui/→ Compose screens + ViewModelsdomain/→ repository contracts/implementations + use-case logicdi/→ Koin module bindings for that feature
Supporting shared/data modules:
data:remote→ Retrofit setup, OkHttp interceptors, API constants/models.data:local→ Room database, DAO, entities, and DataStore-based settings repo.shared:theme→ app theme, reusable UI components, resources.shared:utility→ utility helpers like blur hash decoding.
The app initializes Koin in WallpaperDownloaderApplication and registers modules from app/data/features.
Core idea:
remoteModuleprovidesRetrofit,OkHttpClient, JSON parser.localModuleprovidesWDDatabase,WDDao,SettingsRepository.- Each feature module requests only what it needs (e.g.,
Retrofit,WDDao, dispatchers) and exposesViewModel+ repository bindings.
This keeps feature concerns isolated and testable.
MainActivity hosts a single NavHost with typed destinations (AppDestinations) and a bottom bar for:
- Home
- Favourites
- Authors
Additional routes:
- Category Details
- Wallpaper Details
- Settings
- Author Details
Navigation uses serialized route data classes, allowing strongly typed arguments like Details(id) and AuthorDetails(username).
A typical flow (example: category photos):
- UI triggers ViewModel action.
- ViewModel calls repository/use-case.
- Repository fetches remote data via Retrofit.
- Repository caches/reads entities via Room DAO.
- UI collects Flow/State and recomposes.
Theme flow:
MainViewModelcollects theme fromSettingsRepository(DataStore).- App theme updates in
MainActivityand recomposes globally.
- Application class starts Koin and wires all modules.
MainActivityowns app-wide scaffold + bottom navigation + route graph.MainViewModelexposes app theme state from local settings.
- Category landing screen and category wallpaper listing.
- Home repository handles both network retrieval and category-based local cache stream.
- Includes
HomeUseCasefor concurrently requesting multiple sections.
- Wallpaper detail screen.
- Fetches expanded item details and supports detail actions.
- Favourite wallpapers list and interactions.
- Backed by local storage layer for persisted favourite state.
- Author listing and navigation to author details.
- Author profile/details screen and related author images.
- Settings UI, including theme preference management.
- Retrofit base URL:
https://api.unsplash.com/ - Adds Unsplash
client_idvia OkHttp interceptor usingBuildConfig.ACCESS_KEY. - Configures JSON parser and logging interceptor.
- Room database (
WDDatabase) with migration history. - Entities for photos, users, urls, links, profile images.
- DataStore settings repository for app theme preference.
- Compose theme and reusable UI components.
- Centralized colors, typography, shapes, and drawable resources.
- Utility helpers (e.g., blur hash decoder).
Below are project screenshots pulled from the screenshots/ folder in the repository root.
- Android Studio (recent stable)
- Android SDK (compile/target SDK 35)
- JDK 11
- Unsplash access key
- Clone the repository.
- Create a
local.propertiesfile in project root if missing. - Add your Unsplash key:
ACCESS_KEY=your_unsplash_access_key_hereThe key is injected through Gradle into
BuildConfig.ACCESS_KEYfor modules that apply the shared build logic.
Use Android Studio Run, or CLI:
./gradlew :app:assembleDebug
./gradlew :app:installDebugOptional quality checks:
./gradlew ktlintCheck
./gradlew test- ktlint is applied across subprojects and aggregated into root tasks.
- Multi-module structure improves build isolation and ownership.
- Room schema is exported under
data/local/schemas/for migration visibility.
- Project name in Gradle: Banger.
- Minimum SDK is 24.
- The repository currently stores screenshots in
screenshots/and this README links directly to those assets.





