Skip to content

Latest commit

 

History

History
420 lines (345 loc) · 12.8 KB

File metadata and controls

420 lines (345 loc) · 12.8 KB

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