Getting started
This page takes you from an empty Compose screen to a working paywall. Plan on five minutes.
Requirements
Section titled “Requirements”| Required | |
|---|---|
| minSdk | 26 (Android 8.0) |
| compileSdk | 37 |
androidx.compose.material3 |
1.5.0-beta02 or newer (comes with the library) |
| Kotlin | 2.2 or newer (the library is built with 2.2.10) |
Install
Section titled “Install”-
Add the JitPack repository and the dependency. Pick the tab that matches how your project declares dependencies.
settings.gradle.kts dependencyResolutionManagement {repositories {google()mavenCentral()maven("https://jitpack.io")}}app/build.gradle.kts dependencies {implementation("com.github.sanikantv:m3-expressive-paywall:v1.0.0")}gradle/libs.versions.toml [versions]m3Paywall = "v1.0.0"[libraries]m3-paywall = { module = "com.github.sanikantv:m3-expressive-paywall", version.ref = "m3Paywall" }app/build.gradle.kts dependencies {implementation(libs.m3.paywall)} -
Sync Gradle. The library brings
material3:1.5.0-beta02with it, so you don’t need to add it yourself. -
Add the imports where you build the screen:
import androidx.compose.runtime.Composableimport dev.sanikant.m3.paywall.ClassicPlansPaywallimport dev.sanikant.m3.paywall.PaywallFeatureimport dev.sanikant.m3.paywall.PaywallIconsimport dev.sanikant.m3.paywall.PaywallLegalimport dev.sanikant.m3.paywall.PaywallPlan
Your first paywall
Section titled “Your first paywall”@Composablefun UpgradeScreen(onBuy: (planId: String) -> Unit, onRestore: () -> Unit, onDismiss: () -> Unit) { ClassicPlansPaywall( plans = listOf( PaywallPlan(id = "monthly", title = "Monthly", price = "$4.99", period = "per month"), PaywallPlan( id = "yearly", title = "Yearly", price = "$29.99", period = "per year", trialText = "7-day free trial", badge = "Best value", ), ), features = listOf( PaywallFeature("Unlimited projects", icon = PaywallIcons.Sparkle), PaywallFeature("No ads", icon = PaywallIcons.Block), ), legal = PaywallLegal(termsUrl = "https://example.com/terms", privacyUrl = "https://example.com/privacy"), onPurchase = { plan -> onBuy(plan.id) }, onRestore = onRestore, onClose = onDismiss, )}What each part does:
plans: what the user can buy.priceandperiodare display strings, so pass the localized price your billing SDK gives you. The plan with abadgeis preselected.features: the benefits list. Icons come fromPaywallIcons, or pass anyImageVector.legal: your Terms and Privacy URLs. They open in the browser from the footer.onPurchase: gets the selectedPaywallPlan. Start your billing flow here.onRestoreandonClose: the Restore link and the close button.
Under the button the paywall writes the disclosure line for the selected plan, for example “7-day free trial, then $29.99 per year. Renews automatically until canceled. Cancel anytime in Google Play.”
The paywalls read colors, type and motion from MaterialTheme. For the full Expressive feel,
wrap your app in MaterialExpressiveTheme with MotionScheme.expressive():
@Composablefun AppTheme(typography: Typography = Typography(), content: @Composable () -> Unit) { val dark = isSystemInDarkTheme() val context = LocalContext.current val colors = when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> if (dark) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) dark -> darkColorScheme() else -> expressiveLightColorScheme() } MaterialExpressiveTheme( colorScheme = colors, motionScheme = MotionScheme.expressive(), // MotionScheme.standard() for calmer springs typography = typography, content = content, )}Dynamic color, dark mode and your own font apply automatically. The demo app uses
Google Sans Flex through a variable
FontFamily:
/** A variable font (e.g. Google Sans Flex in res/font) as a FontFamily, one instance per weight. */fun variableFontFamily(@FontRes font: Int): FontFamily = FontFamily( listOf(400, 500, 600, 700, 800, 900).map { weight -> Font(font, FontWeight(weight), variationSettings = FontVariation.Settings(FontVariation.weight(weight))) },)
// Then: AppTheme(typography = Typography(variableFontFamily(R.font.google_sans_flex))) { ... }Next steps
Section titled “Next steps”Built by Sanikant. Set in Google Sans Flex (SIL Open Font License). Not affiliated with Google.