Mavericks, Meet Jetpack Compose

Gabriel Peal
3 min readMar 2, 2021

--

When we first saw Jetpack Compose, we weren’t sure how or even if Mavericks still fit into the picture. Now that we’ve had the chance to learn it and build some simple apps, it’s clear that not only does Mavericks work well with Compose, it arguably works even better than it ever did with classic Android views.

Today, we’re releasing the first alpha of mavericks-compose . Mavericks Compose builds off of the recently-released Mavericks 2.0 release with full support for the Jetpack Compose beta.

To use Mavericks with Compose, add the new artifact to your project that already supports Compose.

com.airbnb.android:mavericks-compose:2.1.0-alpha01

Then, create a MavericksViewModel or pick an existing one you want to use. You don’t have to do anything different to your ViewModel itself to use it in Compose. If you have never used Mavericks before, you can start with our documentation here.

This is a simple CounterViewModel. Its state has a single count property and the ViewModel has one function, incrementCount() .

Access a ViewModel

Now, let’s say you wanted to create or get an instance of this ViewModel from a composable function. To do that, simply call mavericksViewModel() .

By default, this will scope to the nearest LocalLifecycleOwner which will probably be the nearest NavBackStackEntry , Fragment , or Activity . That means that all composables under that LocalLifecycleOwner will get the same ViewModel instance.

If you want to specify a custom scope, you can pass in an optional scope parameter or use the helper mavericksActivityViewModel() .

Access ViewModel State

To subscribe to state changes in your ViewModel, mavericks-compose provides ViewModel.collectAsState() .

To optimally use collectAsState() it is useful to read up on how Compose handles state. Compose is very efficient with its recomposition tracking. Compose recognizes which state properties are accessed by different composables so it can minimize the work that needs to be done when your state changes.

As a result, it is more optimal to subscribe to one or two state properties in a small composable function than it is to subscribe to the entire state class. If you subscribe to the entire state class, your composable will have to recompose any time any state property changes whether or not you actually use it in your composable.

You may also find it beneficial to use the state hoisting pattern. This would split IncrementCount() above into a Mavericks stateful and stateless versions which may make it easier to use things like @Preview .

With this release, we’re more confident than ever that Mavericks will be an excellent complement to Jetpack Compose as it matures and becomes the standard way of writing Android apps for years to come.

--

--

Gabriel Peal

Open source maintainer of Lottie and Mavericks. Full stack at Watershed. Formerly Android at Tonal, Airbnb, and Android Auto at Google.