Skip to content

Repository files navigation

ComposeScreenExample

GitHub repository

Kotlin Multiplatform and Compose Multiplatform architecture and UI laboratory.

ComposeScreenExample develops and compares navigation engines, shared Compose UI patterns, platform integrations, and multiplatform boundaries in one multi-module codebase.

Architecture

Single Activity — Multi Module — Multiple Backstack — MVVM(UiState + UiAction) — Clean Architecture/Redux(one app state)

Navigation

Project uses navigation libs:

Nav3 and Voyager are CMP implementations in commonMain. Compose Navigation, Compose Destinations, and Jetpack Navigation remain Android-only.

Navigation selection is generated from infrastructure/config/build.gradle.kts. Configure debugNavigationLib and releaseNavigationLib there. Do not add navigation-engine branches to the app entry point.

See the navigation toolkit for construction, multiple back stacks, back handling, and adding independent bottom-navigation modules.

Tech Stack

  • Kotlin Multiplatform, coroutines, Flow, and kotlinx serialization.
  • Jetpack Compose, Compose Multiplatform, and Glance.
  • Nav3, Voyager, Compose Navigation, Compose Destinations, and Fragment Navigation.
  • Koin for dependency injection.
  • Ktor for backend communication.
  • Room and DataStore for persistence.
  • Kamera for multiplatform camera preview and video recording.
  • Coil for image loading.
  • Kermit for multiplatform logging.
  • BuildKonfig for generated build configuration.
  • KSP for code generation.
  • Gradle convention plugins in build-logic.
  • Konsist and Detekt for architecture and code-quality checks.

Dependency and tool versions live in gradle/libs.versions.toml. Keep version numbers out of this README so the version catalog remains the source of truth.

Build And Run

Requirements:

  • JDK 24.
  • An Android Studio version compatible with the configured Android Gradle Plugin.
  • An Android SDK matching targetApi in the version catalog.

Use the checked-in Gradle wrapper:

git clone https://github.com/Velord/ComposeScreenExample.git
cd ComposeScreenExample
.\gradlew.bat :app:assembleDevelopDebug

Available environments are develop, qa, stage, and production. Build types are debug and release.

BuildKonfig generates one configuration for each Gradle invocation. Build different environment and build-type combinations in separate invocations.

Common project checks:

.\gradlew.bat :infrastructure:konsist:test
.\gradlew.bat detekt

Individual KMP modules expose focused tasks such as allTests, compileAndroidMain, and compileKotlinDesktop.

Project Documentation

UI Features

Movie Demo

Movie.mp4

Theme Demo

  • Before 8.1 Oreo

themedemobefore8.1

  • Before 11 Red Velvet Cake

themedemobefore11.mp4
  • After 11 Red Velvet Cake

themedemoafter11.mp4

Shape Demo

Screen_recording_20241125_174218.mp4

Shapes and layouts used:

1. TicketShape 2. ArcAtBottomCenterShape 3. PervasiveArcFromBottomLayout

Paths used:

  • TicketPath

246669480-b7bf28f2-5e1e-4eb9-ae53-fe3e8ecffd16

  • ArcAtBottomCenterPath

It is the arc placed in the bottom center of the layout that depends on the progress 246670194-fd752fb4-8e3c-49e8-b1bb-f860138600e8

  • WaveShape

Screenshot_20241125_174739

Modifier Demo

Modifier.Demo.2023.6.28.webm

Custom Modifiers used:

1. Modifier.shimmering()

2. Modifier.blinkingShadow()

3. Modifier.hanging()

4. Modifier.swelling()

Shimmering

  1. Rainbow
.shimmering(
    gradientColorAndPosition = { animatedValue ->
        listOf(
            Color.Red to 0f,
            Color.Green to animatedValue * 0.1f,
            Color.Blue to animatedValue * 0.2f,
            Color.Yellow to animatedValue * 0.3f,
            Color.Magenta to animatedValue * 0.7f,
            Color.Cyan to animatedValue * 0.8f,
            Color.Gray to animatedValue * 0.9f,
            Color.Black to animatedValue,
            Color.White to 1f,
        )
    }
)

ezgif com-crop

  1. Default
.shimmering()

ezgif com-crop

  1. Magenta
.shimmering(
    duration = 2000,
    gradientColorAndPosition = { animatedValue ->
        listOf(
            Color.Magenta to 0f,
            Color.Cyan to animatedValue * 0.3f,
            Color.Gray to animatedValue,
            Color.Magenta to 1f,
        )
    }  
)

ezgif com-crop

  1. SurfaceTint
.shimmering(
    duration = 3000,
    gradientColorAndPosition = { animatedValue ->
        listOf(
            MaterialTheme.colorScheme.surfaceTint to 0f,
            MaterialTheme.colorScheme.tertiary to animatedValue,
            MaterialTheme.colorScheme.surfaceTint to 1f,
        )
    }
)

ezgif com-crop

  1. Reverse
.shimmering(
    duration = 3000,
    gradientColorAndPosition = { animatedValue ->
        listOf(
            MaterialTheme.colorScheme.tertiaryContainer to 0f,
            MaterialTheme.colorScheme.onTertiaryContainer to animatedValue,
            MaterialTheme.colorScheme.tertiaryContainer to 1f,
        )
    },
    reverse = true
)

ezgif com-crop

  1. ReverseRainbow
.shimmering(
    duration = 3000,
    gradientColorAndPosition = { animatedValue ->
        listOf(
            Color.Green to 0f,
            Color.Yellow to animatedValue * 0.1f,
            Color.DarkGray to animatedValue * 0.2f,
            Color.Magenta to animatedValue * 0.3f,
            Color.Cyan to animatedValue * 0.35f,
            Color.Transparent to animatedValue * 0.7f,
            Color.Gray to animatedValue * 0.8f,
            Color.Black to animatedValue * 0.85f,
            Color.White to animatedValue * 0.9f,
            Color.LightGray to animatedValue * 0.95f,
            Color.Red to animatedValue,
            Color.Blue to 1f
        )
    },
    reverse = true
)

ezgif com-gif-maker

Blinking Shadow

  1. GreenReverse
.blinkingShadow(
    elevationMax = 64.dp,
    shape = CardDefaults.shape,
    duration = 3000,
    spotColor = Color.Green
)

ezgif com-crop (1)

  1. RedReverse
.blinkingShadow(
    elevationMax = 16.dp,
    shape = CardDefaults.shape,
    duration = 500,
    spotColor = Color.Red
)

ezgif com-crop

  1. CyanRestart
.blinkingShadow(
    elevationMax = 32.dp,
    shape = shape,
    spotColor = Color.Cyan,
    repeatMode = RepeatMode.Restart
)

ezgif com-crop

Hanging

  1. Default
.hanging()

ezgif com-crop

  1. SmallLeft
.hanging(
    shift = HangingDefaults.shift(
        startRotationAngle = 5,
        endRotationAngle = -20
    ),
    animation = HangingDefaults.animation(duration = 2000)
)

ezgif com-crop

  1. FullRotation
.hanging(
    shift = HangingDefaults.shift(startRotationAngle = 180),
    animation = HangingDefaults.animation(3000)
)

ezgif com-crop

  1. HangingOnRightSide
.hanging(pivotPoint = HangingPivotPoint.Right)

ezgif com-crop

  1. QuickHangingOnLeftSide
.hanging(
    shift = HangingDefaults.shift(10),
    animation = HangingDefaults.animation(300),
    pivotPoint = HangingPivotPoint.Left
)

ezgif com-crop

  1. EpilepsyAtBottom
.hanging(
    shift = HangingDefaults.shift(
        startRotationAngle = 5,
        endRotationAngle = -10
    ),
    animation = HangingDefaults.animation(duration = 80),
    pivotPoint = HangingPivotPoint.Bottom
)

ezgif com-crop

  1. HangingOnCenter
.hanging(
    animation = HangingDefaults.animation(duration = 4300),
    pivotPoint = HangingDefaults.pivot(
        pivotFractionX = 0.5f,
        pivotFractionY = 0.5f
    )
)

ezgif com-crop

Swelling

  1. Default
.swelling()

ezgif com-crop

  1. OneAndAHalf
.swelling(targetScale = 1.5f)

ezgif com-crop

  1. HalfToOnePointTwo
.swelling(
    initialScale = 0.5f,
    targetScale = 1.2f,
    duration = 2000
)

ezgif com-crop

  1. Bounce
.swelling(
    initialScale = 0.7f,
    targetScale = 1.1f,
    duration = 3000,
    easing = EaseInBounce
)

ezgif com-crop

Glance Widget Demo

Glance.Widget.mp4
  • Synced Theme with App

synced.theme.mp4
  • Counter

Counter.Widget.mp4
  • Refreshable Image

Image.Widget.mp4

Phone Number Hint Demo

Phone.Number.Hint.mp4

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages