At ADS ’22, I shared a migration technique from current View-based apps to Compose. On this weblog submit, we check out the best way to apply that technique in follow by finishing the migration of the Sunflower pattern app to Compose.
Earlier than leaping into how we went about migrating the app, it’s useful to “set the scene” and see what the place to begin was for Sunflower earlier than we began the migration.
Sunflower initially was began as a pattern app to showcase finest practices for a number of Jetpack libraries reminiscent of Jetpack Navigation, Room, ViewPager2, and extra. It makes use of Materials Design 2 because the design language and has 5 distinct screens whereby every display is represented as a Fragment. Sunflower was really already partly written in Compose — the plant particulars display was reimplemented in Compose.
Given this place to begin, the subsequent step is to plot a plan emigrate the remainder of the app. Observe that the main target of this weblog submit is emigrate Sunflower to Compose — migrating to Materials 3 is left as a separate activity.
The migration technique to Compose will be summarized in these steps:
- Construct new options with Compose
- Construct a library of frequent UI parts
- Change current options with Compose one display at a time
- Take away Fragments and Navigation element and migrate to Navigation Compose
Since we gained’t be including new options to Sunflower, to finish the migration of Sunflower we will probably be specializing in steps 2–4. Particularly, we will probably be migrating the contents of every display within the app to Compose whereas creating frequent reusable UI components. When all screens are in Compose, we are able to then migrate to Navigation Compose and take away all Fragments (!!) from the app.
Observe that this weblog submit builds on high of the Migrating to Jetpack Compose codelab so in case you are new to migrating to Compose, I encourage you to verify that out first. The codelab walks you thru:
- the best way to add Compose to an current codebase
- the best way to strategy migrating current UI components to Compose separately
- the best way to reuse your app’s XML-based theming in Compose by way of Accompanist Materials Theme Adapter.
With our technique in place, the subsequent query is — which display ought to we migrate first? Let’s check out Sunflower’s screens and navigation construction to assist inform the place we are able to get began.
The entry level to the app is HomeViewPagerFragment
which is carried out as a view pager containing two pages/Fragments — GardenFragment
and PlantListFragment
. If we had been emigrate HomeViewPagerFragment
first, that will contain having to make use of Fragments inside Compose. We might then later should refactor our work as soon as the contained Fragments are transformed to Compose. To avoid wasting us from this problem, ideally every web page must be migrated first earlier than migrating HomeViewPagerFragment
.
Given this construction, we’ll migrate all the opposite screens first (the order doesn’t matter), adopted by migrating HomeViewPagerFragment
final.
I’ll spare you the nitty gritty particulars of migrating every display, although usually the migration course of for every display will be summarized by the next steps outlined beneath. As a result of Sunflower already adopted our structure finest practices and guidances, migrating screens separately was remoted to the UI layer and we didn’t should make modifications to the information layer in any respect.
- Create a screen-level composable (e.g.
PlantListScreen
). - Begin migrating UI components from the corresponding XML by utilizing a “backside up” strategy (i.e. beginning on the leaves of the UI tree and dealing your means up). For easy screens, you are able to do this multi functional change/pull request. However for extra complicated screens, the underside up strategy means that you can make enhancements in smaller increments which will be safer to do.
- Determine if any parts will be reused from earlier screens. For instance, each
GalleryFragment
andPlantListFragment
have comparable checklist merchandise views however with completely different information varieties. - As soon as the display has been created, replace the implementation of the containing Fragment to return a
ComposeView
containing the newly created display wrapped round aMdcTheme
so Sunflower’s current XML theming is utilized to the display.
As well as, for every screen-level composable:
- Create a corresponding composable preview for the display. This allows us to shortly iterate by means of the display being constructed with out having to deploy the whole app to an emulator or machine.
- For posterity, every migrated display has a corresponding UI take a look at that checks fundamental performance for the display.
To see this in motion for every display, discuss with the linked pull requests beneath:
…and now, shifting onto 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 Fragments offer you at that time. In order the final step for the migration course of, we are able to delete Fragments, their related XML information, and any associated dependencies from the app, and use Navigation Compose to route between every display.
The brand new navigation graph in Compose seems like this:
The pull request for this modification will be seen right here.
Observe that Fragment and related useful resource deletion doesn’t essentially must occur because the final step. Actually, each GardenFragment
and PlantListFragment
had been deleted when HomeViewPagerFragment
was migrated to Compose since each Fragments had been used inside a ViewPager2
and weren’t part of the Navigation Part graph.
Migrating Sunflower to Compose was not with out its personal challenges. These weren’t essentially roadblocks that prevented Compose adoption, however somewhat points to be considered throughout migration.
As of this writing, Sunflower is constructed utilizing Materials 2, and to implement the collapsing toolbar habits requires both a handbook implementation of it, or utilizing ComposeView
held throughout the View-based CoordinatorLayout
. You may then talk the nested scroll state again to CoordinatorLayout
by way of Modifier.nestedScroll
and rememberNestedScrollInteropConnection()
. That is exactly what was performed in HomeViewPagerFragment
(see HomeScreen.kt for a code pattern).
A counterpoint to this, nonetheless, is that collapsing toolbars are effectively supported in Compose with Materials 3 — the subsequent era of Materials Design. Migrating Sunflower to Materials 3 would keep away from this concern altogether.
In Compose, state controls the UI so stateful drawables like StateListDrawable
are inherently incompatible with how Compose works. The workaround for that is to make use of a single VectorDrawable
(one of many states within the StateListDrawable
s) and depend on tinting the drawable for various states (see HomeScreen.kt for a code pattern).
For a full checklist of supported drawables in Compose, see Drawable Help.
The final step of the migration course of, which is emigrate to Navigation Compose, was pretty easy to do with Sunflower. This is because of the truth that Sunflower has solely 5 screens to work with and so the migration course of was comparatively straightforward. Nonetheless, for apps which have much more screens, the shortcoming emigrate incrementally to Navigation Compose will be difficult as that change will be fairly giant to do .
There may be an current characteristic request to enhance upon this to allow an incremental migration in order that Navigation Compose will be launched earlier within the migration course of. If this impacts you, you possibly can observe the difficulty right here: https://issuetracker.google.com/points/265480755
General, the migration course of to Compose was easy. It was very satisfying eradicating a number of code and general simplifying the implementation which helps with future upkeep on the app.
What did you suppose? Let me know within the feedback beneath you probably have any questions or have learnings to share in your journey migrating an app to Compose. If you would like a extra hands-on and guided expertise with migrating to Compose, be certain to take a look at our codelab.
Blissful migrating!
P.S.
The migration journey can be documented on GitHub on this doc.