Skip to content

kingrocfella/pokemonapp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

14 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Pokemon Application

A modern Android application built with Jetpack Compose that displays Pokemon data from the PokeAPI. The app features a clean, intuitive interface for browsing Pokemon lists and viewing detailed information about individual Pokemon.

πŸš€ Features

  • Pokemon List View: Browse through a paginated list of Pokemon with names and IDs
  • Pokemon Details: View detailed information about individual Pokemon including:
    • Pokemon name and ID
    • Height
    • High-quality Pokemon images
  • Navigation: Smooth navigation between list and details screens
  • Modern UI: Built with Material Design 3 and Jetpack Compose
  • Image Loading: Efficient image loading with Coil
  • Error Handling: Graceful error handling with user-friendly messages
  • Loading States: Proper loading indicators during data fetching
  • Dependency Injection: Clean architecture with Hilt DI

πŸ—οΈ Architecture

The app follows Clean Architecture with multi-module organization for optimal scalability, testability, and build performance:

Modular Architecture

  • 7 Gradle Modules: Organized by layer and feature for parallel development
  • Clean Architecture Layers: Domain, Data, Presentation clearly separated
  • Feature Modules: Independent, self-contained feature implementations
  • Dependency Inversion: Domain layer is pure Kotlin with no Android dependencies

Architecture Principles

  • MVVM Pattern: Model-View-ViewModel for UI layer
  • Use Cases: Business logic encapsulation in domain layer
  • Repository Pattern: Data layer abstraction
  • Dependency Injection: Hilt for compile-time safe DI
  • State Management: Reactive state with StateFlow and Kotlin Result type
  • Mapper Pattern: Clean separation between DTOs and Domain entities

Module Dependency Graph

:app (Application entry point)
 β”œβ”€β†’ :feature:pokemon-list
 β”œβ”€β†’ :feature:pokemon-details
 β”œβ”€β†’ :data
 β”œβ”€β†’ :core:ui
 └─→ :core:common

:feature:pokemon-list & :feature:pokemon-details
 β”œβ”€β†’ :domain (Use cases)
 β”œβ”€β†’ :data (Repository implementations)
 β”œβ”€β†’ :core:ui (Shared UI components)
 └─→ :core:common (Utilities, models)

:data
 β”œβ”€β†’ :domain (Repository interfaces)
 └─→ :core:common (Shared models)

:core:ui
 └─→ :core:common (Shared models)

:domain
 └─→ Pure Kotlin module (no dependencies)

:core:common
 └─→ Android library (shared utilities)

πŸ“± Screenshots

Click to view app screenshots

Pokemon List Screen Pokemon List Screen - Browse through Pokemon with names and IDs

Pokemon Details Screen Pokemon Details Screen - View detailed Pokemon information

The app consists of two main screens:

  1. Pokemon List Screen: Displays a grid of Pokemon cards with names and IDs
  2. Pokemon Details Screen: Shows comprehensive Pokemon information in a beautiful card layout

πŸ› οΈ Tech Stack

Core Technologies

  • Kotlin: Primary programming language
  • Android SDK: Target SDK 35, Minimum SDK 24
  • Jetpack Compose: Modern UI toolkit
  • Material Design 3: Design system

Libraries & Dependencies

UI & Navigation

  • Jetpack Compose BOM: 2024.12.01
  • Material 3: Modern Material Design components
  • Navigation Compose: 2.9.5 - Type-safe navigation
  • Activity Compose: 1.11.0 - Compose integration
  • Lifecycle ViewModel Compose: 2.9.4 - ViewModel integration

Dependency Injection

  • Hilt Android: 2.48 - Dependency injection framework
  • Hilt Navigation Compose: 1.2.0 - Navigation integration
  • KSP: 1.9.22-1.0.17 - Kotlin Symbol Processing

Networking & Data

  • Retrofit: 2.9.0 - HTTP client for API calls
  • Gson Converter: 2.9.0 - JSON serialization/deserialization
  • Coil Compose: 2.4.0 - Image loading library

Core Android

  • AndroidX Core: 1.17.0 - Core Android functionality
  • Lifecycle Runtime KTX: 2.9.4 - Lifecycle-aware components
  • Kotlin Coroutines Core: 1.5.0 - Coroutine support

Testing

  • JUnit: 4.13.2 - Unit testing framework
  • Mockito: 5.1.1 - Mocking framework
  • Mockito Kotlin: 4.1.0 - Kotlin-friendly mocking
  • Mockito Inline: 5.1.1 - Inline mocking for final classes
  • Kotlin Coroutines Test: 1.7.3 - Coroutine testing utilities
  • AndroidX Core Testing: 2.2.0 - Android testing utilities
  • MockWebServer: 4.11.0 - HTTP server for testing
  • Espresso: 3.7.0 - UI testing framework
  • Compose UI Test: UI testing for Compose

Installation

  1. Clone the repository

    git clone https://github.com/kingrocfella/pokemonapp.git
    cd pokemonapp
  2. Open in Android Studio

    • Open Android Studio
    • Select "Open an existing project"
    • Navigate to the project directory
  3. Sync Project

    • Android Studio will automatically sync the project
    • Wait for Gradle sync to complete
  4. Run the App

    • Connect an Android device or start an emulator
    • Click the "Run" button or press Shift + F10

Building

Build Entire App

# Debug build (all modules)
./gradlew assembleDebug

# Release build (all modules)
./gradlew assembleRelease

Parallel & Cached Builds

The project is configured for optimal build performance:

  • Parallel builds: Multiple modules build simultaneously
  • Build caching: Unchanged modules use cached outputs
  • Incremental compilation: Only changed files recompile

For best performance, ensure gradle.properties includes:

org.gradle.caching=true
org.gradle.parallel=true
org.gradle.configureondemand=true

πŸ“ Project Structure

The project is organized into 7 Gradle modules following Clean Architecture principles:

Mypokemonapplication/
β”œβ”€β”€ app/                                    # πŸ“± Application Module
β”‚   β”œβ”€β”€ src/main/
β”‚   β”‚   β”œβ”€β”€ java/.../
β”‚   β”‚   β”‚   β”œβ”€β”€ MainActivity.kt            # Navigation host
β”‚   β”‚   β”‚   └── PokemonApplication.kt      # @HiltAndroidApp entry point
β”‚   β”‚   β”œβ”€β”€ res/                           # App resources
β”‚   β”‚   └── AndroidManifest.xml
β”‚   └── build.gradle.kts                   # App module configuration
β”‚
β”œβ”€β”€ domain/                                 # 🧠 Domain Module (Pure Kotlin)
β”‚   β”œβ”€β”€ src/main/java/.../domain/
β”‚   β”‚   β”œβ”€β”€ entities/
β”‚   β”‚   β”‚   β”œβ”€β”€ Pokemon.kt                 # Core domain entities
β”‚   β”‚   β”‚   β”œβ”€β”€ PokemonDetail.kt
β”‚   β”‚   β”‚   └── PokemonListResult.kt
β”‚   β”‚   β”œβ”€β”€ repository/
β”‚   β”‚   β”‚   └── PokemonRepository.kt       # Repository interface
β”‚   β”‚   └── usecase/
β”‚   β”‚       β”œβ”€β”€ GetPokemonListUseCase.kt   # Business logic
β”‚   β”‚       └── GetPokemonDetailsUseCase.kt
β”‚   └── build.gradle.kts                   # Pure Kotlin module (java-library)
β”‚
β”œβ”€β”€ data/                                   # πŸ’Ύ Data Module
β”‚   β”œβ”€β”€ src/main/java/.../data/
β”‚   β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”‚   β”œβ”€β”€ ApiService.kt              # Retrofit API interface
β”‚   β”‚   β”‚   └── ApiRoutes.kt               # API endpoints
β”‚   β”‚   β”œβ”€β”€ remote/dto/
β”‚   β”‚   β”‚   β”œβ”€β”€ PokemonListDto.kt          # Network DTOs
β”‚   β”‚   β”‚   └── PokemonDetailsDto.kt
β”‚   β”‚   β”œβ”€β”€ mapper/
β”‚   β”‚   β”‚   └── PokemonMapper.kt           # DTO β†’ Domain mapping
β”‚   β”‚   β”œβ”€β”€ repository/
β”‚   β”‚   β”‚   β”œβ”€β”€ PokemonRepositoryImpl.kt   # Repository implementation
β”‚   β”‚   β”‚   └── PokemonUrlRepository.kt
β”‚   β”‚   β”œβ”€β”€ di/
β”‚   β”‚   β”‚   └── DataModule.kt              # Hilt bindings
β”‚   β”‚   └── modules/
β”‚   β”‚       └── NetworkModule.kt           # Retrofit configuration
β”‚   └── build.gradle.kts
β”‚
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ common/                             # πŸ”§ Core Common Module
β”‚   β”‚   β”œβ”€β”€ src/main/java/.../
β”‚   β”‚   β”‚   β”œβ”€β”€ common/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ screens/ScreenNames.kt # Navigation routes
β”‚   β”‚   β”‚   β”‚   └── utils/Utils.kt         # Utility functions
β”‚   β”‚   β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ViewModelState.kt      # Shared state wrapper
β”‚   β”‚   β”‚   β”‚   └── UISkeletonData.kt      # UI state data
β”‚   β”‚   β”‚   └── services/
β”‚   β”‚   β”‚       └── NavigationService.kt   # Navigation helper
β”‚   β”‚   └── build.gradle.kts
β”‚   β”‚
β”‚   └── ui/                                 # 🎨 Core UI Module
β”‚       β”œβ”€β”€ src/main/java/.../
β”‚       β”‚   β”œβ”€β”€ feature/
β”‚       β”‚   β”‚   └── UISkeleton.kt          # Shared UI components
β”‚       β”‚   └── ui/theme/
β”‚       β”‚       β”œβ”€β”€ Color.kt               # App colors
β”‚       β”‚       β”œβ”€β”€ Theme.kt               # Material theme
β”‚       β”‚       └── Type.kt                # Typography
β”‚       └── build.gradle.kts
β”‚
β”œβ”€β”€ feature/
β”‚   β”œβ”€β”€ pokemon-list/                       # πŸ“‹ Pokemon List Feature Module
β”‚   β”‚   β”œβ”€β”€ src/main/java/.../pokemonlist/
β”‚   β”‚   β”‚   β”œβ”€β”€ PokemonListScreen.kt       # Screen entry point
β”‚   β”‚   β”‚   β”œβ”€β”€ PokemonListViewModel.kt    # ViewModel
β”‚   β”‚   β”‚   β”œβ”€β”€ DisplayPokemonList.kt      # List UI
β”‚   β”‚   β”‚   └── PokemonItem.kt             # Item composable
β”‚   β”‚   └── build.gradle.kts
β”‚   β”‚
β”‚   └── pokemon-details/                    # πŸ“„ Pokemon Details Feature Module
β”‚       β”œβ”€β”€ src/main/java/.../pokemondetails/
β”‚       β”‚   β”œβ”€β”€ PokemonDetailsScreen.kt    # Screen entry point
β”‚       β”‚   β”œβ”€β”€ PokemonDetailsViewModel.kt # ViewModel
β”‚       β”‚   β”œβ”€β”€ DisplayPokemonDetails.kt   # Details UI
β”‚       β”‚   └── PokemonDetailRow.kt        # Row composable
β”‚       └── build.gradle.kts
β”‚
β”œβ”€β”€ static/                                 # πŸ“Έ Documentation Assets
β”‚   β”œβ”€β”€ PokemonListScreen.png
β”‚   └── PokemonDetailsScreen.png
β”‚
β”œβ”€β”€ build.gradle.kts                        # Root build configuration
β”œβ”€β”€ settings.gradle.kts                     # Module declarations
β”œβ”€β”€ gradle.properties                       # Build optimization
β”œβ”€β”€ gradle/
β”‚   └── libs.versions.toml                  # Centralized version catalog
β”œβ”€β”€ ARCHITECTURE_DIAGRAM.md                 # Architecture documentation
β”œβ”€β”€ CLEAN_ARCHITECTURE.md                   # Clean architecture guide
└── README.md                               # This file

πŸ”§ Configuration

API Configuration

The app uses the PokeAPI for Pokemon data:

  • Base URL: https://pokeapi.co/api/v2/
  • Endpoints:
    • /pokemon - Pokemon list with pagination
    • /pokemon/{id} - Individual Pokemon details

Build Configuration

  • Compile SDK: 36
  • Target SDK: 35 (only in :app module)
  • Minimum SDK: 24
  • Java Version: 17
  • Kotlin Version: 1.9.22
  • Compose Compiler: 1.5.8
  • Gradle: 8.11.1
  • AGP (Android Gradle Plugin): 8.9.1
  • Module Count: 7 (1 app + 6 libraries)

Module Build Types

  • Application Module (:app): Uses com.android.application plugin
  • Android Libraries (5 modules): Use com.android.library plugin
  • Pure Kotlin Library (:domain): Uses java-library + kotlin-jvm plugin

πŸ§ͺ Testing

The modular architecture enables fast, isolated testing of individual modules:

Running Tests

Test All Modules

# Run all unit tests
./gradlew test

# Run all Android unit tests
./gradlew testDebugUnitTest

Test Individual Modules (Recommended for TDD)

# Test domain layer only (super fast - pure JVM)
./gradlew :domain:test

# Test data layer only
./gradlew :data:testDebugUnitTest

# Test specific feature
./gradlew :feature:pokemon-list:testDebugUnitTest

# Test with auto-rerun on file changes (TDD mode)
./gradlew :feature:pokemon-list:testDebugUnitTest --continuous

Test Structure by Module

:app/src/test/                      # Integration tests
β”œβ”€β”€ PokemonListViewModelTest.kt
└── PokemonDetailsViewModelTest.kt

:domain/src/test/                   # Pure unit tests (JVM)
└── usecase/
    β”œβ”€β”€ GetPokemonListUseCaseTest.kt
    └── GetPokemonDetailsUseCaseTest.kt

:data/src/test/                     # Repository tests
└── repository/
    └── PokemonRepositoryImplTest.kt

:feature:pokemon-list/src/test/     # Feature tests
└── PokemonListViewModelTest.kt

:core:common/src/test/              # Utility tests
└── utils/UtilsTest.kt

Test Coverage

  • Unit Tests: Test business logic in isolation
  • ViewModel Tests: Test state management and UI logic
  • Repository Tests: Test data layer with MockWebServer
  • Mockito Integration: Mock external dependencies
  • Coroutine Testing: Test async operations with StandardTestDispatcher
  • Test Fixtures: Reusable fakes and test data

About

An android application that consumes the publicly available pokemon API.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages