Migrating Sunflower to Jetpack Compose | by Chris Arriola | Android Developers | Feb, 2023 | Creed Tech

Posted on

At ADS ’22, I shared a technique for migrating present View-based functions to Compose. On this weblog submit, we talk about easy methods to apply that technique in apply by finishing the migration of the Sunflower pattern app to Compose.

Sunflower Photographs

Earlier than starting the appliance migration, it is useful to “set the stage” and see what the start line was for Sunflower earlier than we began the migration.

Sunflower was initially began as a pattern utility to reveal greatest practices for numerous Jetpack libraries equivalent to Jetpack Navigation, Room, ViewPager2, and extra. It makes use of Materials Design 2 as its design language and has 5 totally different screens the place every display screen is rendered as a Fragment. Really, Sunflower was already partially written in Compose: the plant particulars display screen was re-implemented in Compose.

Given this start line, the following step is to design a plan emigrate the remainder of the appliance. Please word that the main focus of this weblog submit is migrating Sunflower to Compose; migration to Materials 3 is left as a separate activity.

The migration technique to Compose could be summarized in these steps:

  1. Create new options with Compose
  2. Create a library of frequent UI elements
  3. Change present options with Compose one display screen at a time
  4. Take away the Fragments and Navigation element and migrate to Compose Navigation

Since we cannot be including any new options to Sunflower, to finish the Sunflower migration, we’ll concentrate on steps 2-4. Particularly, we’ll migrate the content material of every app display screen to Compose whereas creating frequent reusable UI components. When all screens are in Compose, we are able to migrate to Navigation Compose and take away all fragments (!!) of the app.

Notice that this weblog submit is predicated on the Migrating to Jetpack Compose code lab, so when you’re new to migrating to Compose, I encourage you to evaluate it first. The codelab guides you thru:

  • easy methods to add Compose to an present code base
  • easy methods to strategy migrating present UI components to Compose one after the other
  • easy methods to reuse your app’s XML-based theme in Compose by way of the Companion Theme Adapter.

With our technique in place, the following query is: which display screen ought to we migrate first? Let’s check out Sunflower’s screens and navigation construction to see the place to start out.

Sunflower Navigation Chart

The entry level to the appliance is HomeViewPagerFragment Which is applied as a pager containing two pages/Fragments: GardenFragment and PlantListFragment. if we needed to migrate HomeViewPagerFragment First, that will imply having to make use of Fragments inside Compose. We’d then have to refactor our work as soon as the contained Fragments are transformed to Compose. To save lots of us from this problem, ideally every web page ought to be migrated first earlier than migrating HomeViewPagerFragment.

Given this construction, we’ll first migrate all different screens (the order does not matter), after which we’ll migrate HomeViewPagerFragment final.

Order of migration screens

I’ll spare you the important particulars of migrating every display screen, however normally the migration course of for every display screen could be summarized within the following steps beneath. As a result of Sunflower already adopted our architectural greatest practices and guides, migrating one display screen at a time was remoted to the UI layer and we did not must make any adjustments to the information layer.

  1. Create a composable on the display screen degree (eg. PlantListScreen).
  2. Begin migrating UI components from the corresponding XML utilizing a “bottom-up” strategy (that’s, beginning on the leaves of the UI tree and dealing your manner up). For easy screens, you are able to do all of this in a single change/pull request. However for extra complicated shows, the bottom-up strategy permits you to make enhancements in smaller increments which may be safer.
  3. Establish if any element from earlier screens could be reused. For instance, each GalleryFragment and PlantListFragment they’ve comparable record merchandise views however with totally different information sorts.
  4. As soon as the display screen has been created, replace the implementation of the wrapper Fragment to return a ComposeView containing the newly created display screen wrapped round a MdcTheme so the prevailing Sunflower XML theme is utilized to the display screen.

Additionally, for every composable on the display screen degree:

  1. Create a corresponding composite preview for the display screen. This enables us to shortly iterate by means of the display screen being created with out having to deploy your complete app to an emulator or gadget.
  2. For posterity, every migrated display screen has a corresponding UI check that exams the fundamental performance of the display screen.

To see this in motion for every display screen, take a look at the pull requests linked beneath:

…and now shifting on to the final (and most satisfying) step of the migration course of 🥁

As soon as all screens have been migrated to Compose, there’s little or no profit that snippets present you at that time. So, because the final step to the migration course of, we are able to take away the fragments, their related XML information, and any associated app dependencies, and use Navigation Compose to route between every display screen.

The brand new navigation chart in Compose seems to be like this:

The pull request for this modification could be seen right here.

Notice that eradicating fragments and related assets doesn’t essentially must be the final step. In reality, each GardenFragment and PlantListFragment have been deleted when HomeViewPagerFragment migrated to Compose as each snippets have been used inside a ViewPager2 and weren’t a part of the navigation element graphic.

The migration from Sunflower to Compose was not with out its challenges. These weren’t essentially roadblocks that prevented Compose adoption, however relatively points to think about throughout migration.

As of this writing, Sunflower is constructed with Materials 2, and implementing the collapsed toolbar conduct requires both a guide implementation or the usage of ComposeView inside view primarily based CoordinatorLayout. You possibly can then talk the nested scroll state again to CoordinatorLayout by means of Modifier.nestedScroll and rememberNestedScrollInteropConnection(). That is exactly what was accomplished in HomeViewPagerFragment (see HomeScreen.kt for a code instance).

Nevertheless, a counterpoint to that is that collapsible toolbars are properly supported in Compose with Materials 3, the following technology of Materials Design. Migrating Sunflower to Materials 3 would keep away from this drawback solely.

In Compose, state controls the UI, so stateful drawables like StateListDrawable they’re inherently incompatible with how Compose works. The answer for that is to make use of a single VectorDrawable (one of many states of the StateListDrawables) and depends on tinting the drawable for various states (see HomeScreen.kt for a code pattern).

For a full record of drawables supported in Compose, see Drawable Help.

The final step of the migration course of, which is migrating to Navigation Compose, was fairly straightforward to do with Sunflower. This is because of the truth that Sunflower solely has 5 screens to work with, so the migration course of was comparatively straightforward. Nevertheless, for functions which have many extra screens, the lack to step by step migrate to Navigation Compose could be difficult, as that change could be fairly massive to do it .

There’s an present characteristic request to enhance this to permit for an incremental migration in order that Navigation Compose could be introduced in earlier within the migration course of. If this impacts you, you’ll be able to monitor the problem right here: https://issuetracker.google.com/points/265480755

Total, the method of migrating to Compose was clean. It was very satisfying to take away a number of code and customarily simplify the deployment, which helps with future upkeep of the app.

That you simply thought? Let me know within the feedback beneath when you have any questions or learnings to share in your utility migration journey to Compose. In order for you a extra hands-on, guided expertise with migrating to Compose, remember to take a look at our code lab.

Glad migration!


The migration journey can be documented on GitHub on this doc.

Migrating Sunflower to Jetpack Compose | by Chris Arriola | Android Developers | Feb, 2023