Skip to content

Latest commit

 

History

History
90 lines (73 loc) · 4.39 KB

README.md

File metadata and controls

90 lines (73 loc) · 4.39 KB

Delight — Android app base template

A base repo for design-forward Android apps: Kotlin + Compose Multiplatform (Android target today, iOS-ready tomorrow) + Material 3 + physics-based motion.

Every "delight" technique ships as a working demo screen — clone, run, steal.

Stack

Concern Choice
Language Kotlin (multiplatform)
UI Compose Multiplatform 1.9.0 — all UI lives in commonMain
Design system Material 3 + Material You dynamic color, extra-round expressive shapes
State Coroutines + Flow, collectAsStateWithLifecycle, ViewModel
DI (add Hilt or Koin when the app grows)
Navigation Tiny state-driven Navigator routed through AnimatedContent
Build AGP 8.10 / Gradle 8.14 / Kotlin 2.2

Why Compose Multiplatform with an Android-only target?

The composeApp module is a standard KMP module — it just only declares androidTarget(). When iOS lands on the roadmap, add the iOS targets in composeApp/build.gradle.kts (marked with a comment), a SwiftUI shell, and done — every screen in commonMain is already multiplatform-safe. Platform differences are isolated behind expect/actual in platform/ (see Platform.android.kt for dynamic color, back handling, and AGSL shaders).

The delight layer — where each technique lives

Technique Demo Source
Spring physics (spring(), Animatable, interruptible motion) Drag-the-ball playground with damping/stiffness sliders ui/SpringsScreen.kt
Shared element transitions (SharedTransitionLayout + sharedElement) Grid → detail hero animation ui/SharedElementsScreen.kt, root layout in App.kt
AnimatedVisibility / AnimatedContent / animateContentSize Toggle card, counter, expanding card ui/MotionScreen.kt
Animated nav transitions Screen-to-screen slide/fade via AnimatedContent App.kt
AGSL RuntimeShader + graphicsLayer Animated shader backdrop + 3D-tilting card ui/GraphicsScreen.kt, platform/Platform.android.kt
Haptics (LocalHapticFeedback) Tick vs. thud vs. snap, press-and-hold squash ui/HapticsScreen.kt
Material 3 Expressive-adjacent components Segmented buttons, progress, expressive shapes ui/ExpressiveScreen.kt, theme/Theme.kt
Material You dynamic color Automatic on Android 12+ theme/Theme.kt
Staggered entrances Home list items cascade in ui/HomeScreen.kt
Predictive back enableOnBackInvokedCallback in the manifest AndroidManifest.xml
Edge-to-edge enableEdgeToEdge() (mandatory on targetSdk 35 anyway) MainActivity.kt

Project layout

composeApp/
  src/
    commonMain/kotlin/dev/delight/app/
      App.kt                  # theme + SharedTransitionLayout + animated nav host
      navigation/Navigator.kt # minimal state-driven back stack
      theme/Theme.kt          # M3 theme, dynamic color hook, expressive shapes
      platform/Platform.kt    # expect declarations (dynamic color, back, shader)
      model/                  # ViewModel + demo data
      ui/                     # one file per demo screen
    androidMain/
      AndroidManifest.xml     # predictive back, edge-to-edge
      kotlin/.../MainActivity.kt
      kotlin/.../platform/Platform.android.kt  # actual implementations

Adding iOS later

  1. In composeApp/build.gradle.kts: add iosX64(); iosArm64(); iosSimulatorArm64() next to androidTarget().
  2. Create iosMain actuals for the three expect declarations in platform/Platform.kt (all have sensible fallbacks).
  3. Add an iosApp Xcode project that calls MainViewController().
  4. For production navigation, migrate Navigator to Navigation 3 (androidx.navigation3) or CMP navigation-compose with serialized keys — both give process-death restoration and predictive back previews.

Performance guardrails (delight dies at jank)

  • release build already enables R8 + resource shrinking.
  • Add Baseline Profiles (androidx.baselineprofile) and Macrobenchmark before launch.
  • Use Compose compiler metrics (composeCompiler { reportsDestination }) to audit stability/skippability.
  • Coil 3 for images; Rive or Lottie for hero animations — add when needed.

Build

./gradlew :composeApp:assembleDebug

Requires JDK 17+ and Android SDK 35 (local.properties → sdk.dir=..., or ANDROID_HOME).