Enhance in-app purchase experiences with slide to unlock in Jetpack Compose

In this article, you’ll explore the open-source slide-to-unlock library, built by RevenueCat, and learn how to integrate it with RevenueCat’s in-app purchases in Jetpack Compose

Jaewoong Eum
Published

When Apple first introduced the “Slide to Unlock” feature on the iPhone, it wasn’t just a quirky design, it was a deliberate interaction choice. Compared to a normal button, sliding offered a more engaging and meaningful way to unlock a device.

While newer devices have replaced “Slide to Unlock” with swipe gestures or biometric unlocking, the underlying principle remains the same: interaction should feel intentional, intuitive, and rewarding. Apple’s slider was one of the earliest examples of how even a simple UI decision can influence user engagement.

In this article, you’ll explore the open-source slide-to-unlock library, built by RevenueCat, and learn how to integrate it with RevenueCat’s in-app purchases in Jetpack Compose through practical, real-world examples.

Slide to unlock in Jetpack Compose

The slide-to-unlock library is designed for Kotlin Multiplatform, so you can use it in both Android and KMP projects. To add slide-to-unlock to your project, include the following dependency in your Gradle file:

1implementation("com.revenuecat.purchases:slide-to-unlock:1.0.2")

For Kotlin Multiplatform, add the dependency below to your module’s build.gradle.kts file:

1sourceSets {
2    val commonMain by getting {
3        dependencies {
4            implementation(libs.compose.slidetounlock)
5        }
6    }
7}
8

The usage is pretty simple. You can just implement it by using the `SlideToUnlock` composable with creating a state at the call site like below:

1var isSlided by remember { mutableStateOf(false) }
2
3SlideToUnlock(
4    isSlided = isSlided,
5    modifier = Modifier.fillMaxWidth(),
6    onSlideCompleted = { isSlided = true },
7)

SlideToUnlock is highly customizable, you can adjust nearly every aspect of the slider, including colors, thumb, hint text, gesture behavior, and tracking slide fractions. You can also provide your own composables for the thumb and hint to achieve a fully tailored experience. For more details on customization, please refer to the documentation.

RevenueCat integration

This library supports RevenueCat integration, allowing you to easily implement features like Slide to Purchase or Slide to Subscribe by adding the dependency below:

1implementation("com.revenuecat.purchases:slide-to-unlock-purchases:1.0.2")

You can now use the SlideToPurchases component, which triggers in-app purchases once the slide action is completed. Its usage is very similar to the SlideToUnlock composable, but it requires a few additional parameters needed to complete purchases through the RevenueCat SDK.

The library provides several overloaded SlideToPurchases composables to cover different purchase scenarios, such as product types, subscription upgrades, and promotional offers, while abstracting away the underlying purchase logic.The most common use case is simple: fetch your offerings from RevenueCat and pass the desired Package to the composable. The component takes care of everything else.

1// inside your coroutine scope
2val currentOffering = Purchases.sharedInstance.awaitOfferings().current
3val monthlyPackage = currentOffering?.getPackage("monthly")
4
5if (monthlyPackage != null) {
6    var purchaseState by remember { mutableStateOf<PurchaseState?>(null) }
7
8    SlideToPurchases(
9        packageToPurchase = monthlyPackage,
10        modifier = Modifier
11            .fillMaxWidth()
12            .padding(16.dp),
13        onPurchaseStateChanged = { newPurchaseState ->
14            purchaseState = newPurchaseState
15            // Handle state changes, e.g., show a dialog on success/error
16        }
17    )
18
19    // Optionally display the state
20    when (val state = purchaseState) {
21        is PurchaseState.Loading -> { /* Show a loading indicator */ }
22        is PurchaseState.Success -> { /* Navigate to a success screen */ }
23        is PurchaseState.Error -> { /* Show an error message */ }
24        null -> { /* Initial state */ }
25    }
26}

Similar to the Purchases.sharedInstance.awaitPurchase() function, you can perform in-app purchases using several options: StoreProduct, Package, SubscriptionOption, PromotionalOffer, and WinBackOffer. For more details, check out the overloads documentation.

Building a custom paywalls with slide to unlock

Now let’s take a look at how to build a custom paywall that includes Slide to Unlock. If you want to create your own custom paywalls, you can achieve it by using RevenueCat’s Paywall Editor, which is based on a server-driven UI

However, if you need a more personalized design, such as containing very customized UI components that aren’t supported by the Paywall Editor, you’ll need to create your own custom paywalls. In that case, you can manually fetch the current offerings and render the screens based on your requirements.

Currently, RevenueCat’s Paywall Editor doesn’t support Slide to Unlock officially, so in this article we’ll walk through a workaround for integrating it into your custom paywalls. First things first: open the RevenueCat Paywall Editor and create a new paywall without a footer, leaving enough space at the bottom like the image below:

Next, fetch the current offering as shown in the code below:

1try {
2  val offerings = Purchases.sharedInstance.awaitOfferings()
3  offerings.current?.let { currentOffering ->
4    // you have a current offering now here
5  }
6} catch (e: PurchasesException) {
7  // fetching offering exception
8}

Then, retrieve the available package information from the offering and position the Paywall composable component alongside SlideToUnlock, as demonstrated here:

1 Box(
2    modifier = Modifier
3      .fillMaxSize()
4      .background(Color.White),
5  ) {
6    Paywall(
7      options = PaywallOptions.Builder(
8        dismissRequest = { viewModel.navigateUp() },
9      ).setOffering(offering).build(),
10    )
11
12    val availablePackage = offering?.availablePackages?.first()
13    val activity = (LocalContext.current as? Activity)
14    var isSlided by remember { mutableStateOf(false) }
15    
16    if (availablePackage != null && activity != null) {
17      SlideToUnlock(
18        modifier = Modifier
19          .align(Alignment.BottomCenter)
20          .fillMaxWidth()
21          .padding(bottom = 60.dp, start = 20.dp, end = 20.dp),
22        isSlided = isSlided,
23        hintTexts = HintTexts.defaultHintTexts().copy(
24          defaultText = stringResource(
25            com.revenuecat.articles.paywall.compose.core.designsystem.R.string.slide_subscribe,
26          ),
27        ),
28        onSlideCompleted = {
29          isSlided = true
30          viewModel.handleEvent(
31            PaywallEvent.Purchases(
32              activity = activity,
33              availablePackage = availablePackage,
34            ),
35          )
36        },
37      )
38    }
39  }
40

That’s it! You’ll now see the result below, a seamless combination of the paywall you built in the Paywall Editor and the Slide to Unlock component.

You can check out the full source code on GitHub, an open source project Cat Paywall Compose’s paywalls directory.

Wrapping Up

In this article, you’ve learned how to use the slide-to-unlock library and integrate it into a custom paywall. While RevenueCat’s Paywall Editor offers a fast and convenient way to build paywalls, sometimes you’ll want to go further and experiment with more personalized or playful interactions.

There are many strategies to increase user engagement and improve subscription conversion rates, clear value communication, compelling design, optimized pricing, and interactive UI patterns all play a role. Slide to Unlock adds an extra layer of interactivity that feels intuitive, deliberate, and rewarding for users, helping to reduce friction and increase commitment to the purchase flow.

As you continue refining your paywalls, consider testing different designs, messaging, and engagement patterns to find what resonates best with your audience. Combined with RevenueCat’s analytics and A/B testing capabilities, approaches like slide-to-unlock can be great tools in building subscription experiences that are not only effective but also enjoyable.

You might also like

Share this post