Creating Onboarding Flow with MotionLayout

Ernest Saidu Kamara
Ernest Saidu Kamara | 9 January, 2020

Ernest Saidu KamaraThe Android platform offers the ability to completely customise components that are not available in the prebuilt widgets and layouts or modify some existing components to meet our needs. However, making apps more accessible with complex UI requires some additional effort and sometimes nearly impossible. Fortunately, the Android team are continuously working to help us resolve some of these constraints by adding new classes and support libraries to the platform, such as ConstraintsLayout

Disclaimer: This article assumes that you’re familiar with MotionLayout and Circular Positioning with ConstraintsLayout. If not I recommend Introduction to MotionLayout (part I) by Nicolas Roard and ConstraintLayout: Circular Positioning by Andrew Kelly as a starting point.

Recently, I was assigned a task to create an onboarding flow with multiple screens for a client, to showcase a new feature in their Android app. Usually, I’d build such onboarding flow using a ViewPager and animates between these screens using transitions. But this time, I chose to build it with MotionLayout after some reading and tutorials on MotionLayout.

In this article, I’m going to take you through my journey of creating this onboarding flow with MotionLayout.

The Onboarding Flow

The onboarding flow(see gif below) comprises of three screens with two control buttons and a progress dot indicator. Each screen incorporates details about that specific screen, encased in a bubble background.

Navigating to the next or previous screen animates to the next or previous screen respectively along with the progress indicator getting updated. The details in the bubble are only visible when the bubble expands and obscure when shrinks.



Why using MotionLayout?

At a glance at the gif, using MotionLayout may appear irrelevant to you, but allow me to elaborate. First of all, before MotionLayout, I felt terrible at animations on Android, especially when dealing with custom views. I’d build it by creating a custom view along with the texts and images to a canvas.

Secondly, it is nearly impossible to get this right without callbacks in my animations implementation — probably, some more boilerplate code.

Finally, making these screens accessible isn’t going to be easy based on experience. I’d also need a custom AccessibilityDelegate for my virtual views.

Fortunately, with MotionLayout, I don’t need to worry about all these issues and allows me to focus on the main logic of the onboarding flow.

MotionLayout is a subclass of ConstraintsLayout and helps with widgets animations. Moreover, ConstraintsLayout already supports circular positioning and works as the solution used in this article.

The Onboarding Layout

Earlier, I stated that the onboarding comprises of three screens. Which sounds like I’d also need three separate layouts, but with MotionLayout, it is possible to use a single layout for these screens using constraint set for each screen. Cool, right?

Onboarding design and blueprint

Furthermore, since the bubbles have different details for styling based on design specifications, one way of tackling this is to add all the views in our layout and then position them independently. This approach can result in one large layout file, which is challenging to maintain.

However, I favoured creating a new layout class, i.e. OnboardingbubbleItemthat subclasses FrameLayout. OnboardingbubbleItem inflates a view of the bubble, i.e. layout_bubble_item.xml. I strongly recommend this approach as customising is more straightforward with custom attributes and MotionLayout now treats these views as its direct children.

Each OnboardingbubbleItem is then circularly constrained from a centre point widget centerPointPlaceholder at a given distance and radius for both expand and obscure details states in the onboarding_motion_layout.xml and the constraint set transitions in onboarding_scene.xml

By default, MotionLayout uses MotionScene, a separate file containing the animation specifications needed to transition from the start-position to the end-position of our screen.

But, since the onboarding contains more than two screens and I’d need more than two transitions for the onboarding flow to work. In other words, I’d need to transition from one state to the other. I choose to do this by code since handling these transitions in the MotionScene file along with the progress indicator, and button state is very tricky in my opinion. However, if you have a better approach, please share in the comment section below.

As mentioned earlier, transitioning between the next and previous screen is accomplished programmatically in the OnboardingFragment, the Fragmentthat hosts the onboarding flow. Notices how the extension function navigate is implemented. It updates the progress indicator and buttons states and sets the transition between the start and end constraint sets. Then animates to the ending position with motionLayout.transitionToEnd().

That’s all. Now you know how I built an onboarding flow with MotionLayout. The full sample is available on Github.

Lastly, I reached out to Nicolas Roard from the ConstraintsLayout team at Google for help and tipped me on how to make this onboarding work with less code. So stay tuned for part two of this article. See you soon!

Thank you for reading. I’d love to hear your feedback, so please leave me a comment below.

Ernest is an Android professional, with experience in developing and maintaining high quality scalable Android applications. Ernest is currently working as a Senior Android consultant at DNB(MinBank) via Shortcut, previously EVRY (Digital banking services) and Zedge Inc. Ernest enjoys taking photos and playing soccer with his kids when he is not co-organising meetups for his local developer community.

This post was originally posted on Ernests blog on Medium.


android MotionLayout UI