Skip to content

Android Product App using FakeStoreAPI, MVVM, and Jetpack Compose.

License

Notifications You must be signed in to change notification settings

elvynedinson/ProductApp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

21 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ›οΈ ProductApp - Modern Android Development

Kotlin Jetpack Compose Android Material Design

E-commerce Android app showcasing modern development practices

MVVM β€’ Clean Architecture β€’ Jetpack Compose β€’ Hilt

πŸš€ Features β€’ πŸ— Architecture β€’ πŸ›  Tech Stack β€’ πŸ“¦ Installation


πŸ“± About

ProductApp is a learning-focused Android application built with Kotlin and Jetpack Compose. This project demonstrates modern Android development best practices, including:

  • 🎯 Clean Architecture principles
  • πŸ”„ Reactive programming with StateFlow
  • πŸ’‰ Dependency Injection with Hilt
  • 🎨 Modern UI with Jetpack Compose
  • 🌐 REST API consumption

πŸ“Œ This is an educational project developed step-by-step with incremental commits and well-documented architectural decisions.


✨ Features

πŸ›’ Core Functionality

  • βœ… Product Listing - Browse products from FakeStore API
  • βœ… Image Loading - Efficient image caching with Coil
  • βœ… Pull to Refresh - Update product list
  • βœ… Error Handling - Graceful error states with retry mechanism
  • βœ… Loading States - Smooth UX with loading indicators

🎨 User Interface

  • βœ… Material Design 3 - Modern, beautiful UI components
  • βœ… Responsive Layout - Adapts to different screen sizes
  • βœ… Dark Theme Support - System-based theme switching
  • βœ… Smooth Animations - Native Compose animations

πŸ”§ Technical Features

  • βœ… State Management - Predictable UI states (Loading/Success/Error)
  • βœ… Reactive UI - StateFlow-based reactive updates
  • βœ… Type-Safe Navigation - Compose Navigation (planned)
  • βœ… Offline Support - Room caching (planned)

πŸ— Architecture

MVVM + Clean Architecture (Base)

The project follows a clean, scalable architecture pattern:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         PRESENTATION LAYER              β”‚
β”‚    (Compose UI + ViewModels)            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚         DOMAIN LAYER                    β”‚
β”‚         (Use Cases - Planned)           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚           DATA LAYER                    β”‚
β”‚     (Repository + Data Sources)         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚         EXTERNAL SERVICES               β”‚
β”‚      (Retrofit + FakeStore API)         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‚ Project Structure

app/
β”œβ”€β”€ ui/
β”‚   β”œβ”€β”€ screen/
β”‚   β”‚   └── ProductListScreen.kt      β†’ Main product screen
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ ProductCard.kt            β†’ Reusable product card
β”‚   β”‚   β”œβ”€β”€ LoadingIndicator.kt       β†’ Loading state UI
β”‚   β”‚   └── ErrorView.kt              β†’ Error state UI
β”‚   β”œβ”€β”€ state/
β”‚   β”‚   └── UiState.kt                β†’ Sealed class for UI states
β”‚   └── viewmodel/
β”‚       └── ProductViewModel.kt       β†’ Business logic & state
β”‚
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ model/
β”‚   β”‚   └── Product.kt                β†’ Data models
β”‚   β”œβ”€β”€ repository/
β”‚   β”‚   └── ProductRepository.kt      β†’ Single source of truth
β”‚   └── remote/
β”‚       └── ApiService.kt             β†’ Retrofit API interface
β”‚
└── di/
    └── NetworkModule.kt              β†’ Hilt DI configuration

πŸ”„ Data Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   UI     β”‚ ───> β”‚  ViewModel   β”‚ ───> β”‚ Repository β”‚ ───> β”‚   API   β”‚
β”‚ (Compose)β”‚ <─── β”‚ (StateFlow)  β”‚ <─── β”‚  (Single   β”‚ <─── β”‚(Retrofit)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚   Source)  β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  1. UI observes ViewModel's StateFlow
  2. ViewModel requests data from Repository
  3. Repository fetches from API (or cache - future)
  4. Data flows back as UiState (Loading β†’ Success/Error)

🧠 State Management

UiState Pattern

The app uses a sealed class to represent all possible UI states:

sealed class UiState<out T> {
    object Loading : UiState<Nothing>()
    data class Success<T>(val data: T) : UiState<T>()
    data class Error(val message: String) : UiState<Nothing>()
}

Benefits

  • βœ… Type-safe - Compiler guarantees all states are handled
  • βœ… Predictable - UI always reflects current state
  • βœ… Testable - Easy to unit test state transitions
  • βœ… Maintainable - Clear separation of concerns

State Flow Example

// ViewModel
private val _uiState = MutableStateFlow<UiState<List<Product>>>(UiState.Loading)
val uiState: StateFlow<UiState<List<Product>>> = _uiState.asStateFlow()

// UI (Compose)
val state by viewModel.uiState.collectAsState()

when (state) {
    is UiState.Loading -> LoadingIndicator()
    is UiState.Success -> ProductList(state.data)
    is UiState.Error -> ErrorView(state.message, onRetry = { viewModel.retry() })
}

πŸ› οΈ Tech Stack

Core Technologies

Kotlin: 1.9.0+
β”œβ”€β”€ Coroutines - Asynchronous programming
└── Flow/StateFlow - Reactive streams

Android
β”œβ”€β”€ compileSdk: 34
β”œβ”€β”€ minSdk: 24 (Android 7.0)
└── targetSdk: 34

Jetpack Libraries

Jetpack Compose
β”œβ”€β”€ Compose UI: 1.5.4
β”œβ”€β”€ Compose Material3: 1.1.2
β”œβ”€β”€ Compose Navigation: 2.7.5 (planned)
└── Compose Runtime

AndroidX
β”œβ”€β”€ Core KTX: 1.12.0
β”œβ”€β”€ Lifecycle ViewModel: 2.6.2
β”œβ”€β”€ Activity Compose: 1.8.1
└── Lifecycle Runtime: 2.6.2

Networking & Data

Retrofit: 2.9.0
β”œβ”€β”€ Converter Gson - JSON parsing
└── OkHttp - HTTP client

Image Loading
└── Coil Compose: 2.5.0

Dependency Injection

Hilt: 2.48
β”œβ”€β”€ Hilt Android
└── Hilt Compiler

API

FakeStore API
└── https://fakestoreapi.com
    β”œβ”€β”€ GET /products - List all products
    └── GET /products/{id} - Product details (planned)

πŸ“¦ Installation

Prerequisites

# Required versions
- Android Studio: Hedgehog | 2023.1.1 or newer
- JDK: 17 or higher
- Kotlin: 1.9.0+
- Gradle: 8.0+

Setup Instructions

  1. Clone the repository
git clone https://github.com/elvynedinson/ProductApp.git
cd ProductApp
  1. Open in Android Studio
# File β†’ Open β†’ Select ProductApp folder
  1. Sync Gradle
# Android Studio will automatically sync
# Or manually: File β†’ Sync Project with Gradle Files
  1. Run the app
# Select device/emulator
# Click Run button or Shift+F10

Build Variants

# Debug build
./gradlew assembleDebug

# Release build (requires signing config)
./gradlew assembleRelease

# Install on device
./gradlew installDebug

🎯 Best Practices Implemented

Code Quality

  • βœ… Single Responsibility - Each class has one clear purpose
  • βœ… Dependency Inversion - Depend on abstractions, not implementations
  • βœ… Immutability - Data classes are immutable
  • βœ… Type Safety - Leveraging Kotlin's type system

Architecture

  • βœ… Separation of Concerns - UI, Business Logic, Data are separated
  • βœ… Unidirectional Data Flow - Data flows in one direction
  • βœ… Single Source of Truth - Repository pattern
  • βœ… Reactive UI - State-driven UI updates

Development

  • βœ… Incremental Development - Small, focused commits
  • βœ… Descriptive Commits - Clear commit messages
  • βœ… Code Comments - Explaining "why", not "what"
  • βœ… Kotlin Conventions - Following official style guide

Performance

  • βœ… Efficient Recomposition - Using remember and derivedStateOf
  • βœ… Image Caching - Coil handles caching automatically
  • βœ… Coroutine Scoping - Proper lifecycle-aware coroutines
  • βœ… State Hoisting - Reusable, stateless composables

Current State

The project is being built with testability in mind, though tests are not yet implemented.


πŸ“š Learning Resources

This project was built following industry best practices and official documentation:


🀝 Contributing

This is a personal learning project, but suggestions and feedback are welcome!

If you want to contribute:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

πŸ“„ License

This project is open source and available under the MIT License.


πŸ‘¨β€πŸ’» Developer

Elvyn Edinson

Android Developer in training πŸš€

Skills Demonstrated

  • βœ… Kotlin
  • βœ… Jetpack Compose
  • βœ… MVVM Architecture
  • βœ… Clean Architecture Principles
  • βœ… Dependency Injection (Hilt)
  • βœ… Reactive Programming (Coroutines, Flow)
  • βœ… REST API Integration
  • βœ… Material Design 3

πŸ™ Acknowledgments

  • FakeStore API for providing the free REST API
  • Android Community for excellent documentation and support
  • JetBrains for Kotlin and IntelliJ IDEA
  • Google for Android and Jetpack libraries

πŸ“Š Project Stats

Lines of Code: ~500 (and growing)
Commits: Incremental and descriptive
Architecture: MVVM + Clean Architecture
UI Framework: 100% Jetpack Compose

⭐ If you find this project helpful, consider giving it a star!

Built with ❀️ using Kotlin + Jetpack Compose

*Learning by doing, following real

About

Android Product App using FakeStoreAPI, MVVM, and Jetpack Compose.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages