Inside PhotoroomStories from the team

Redesigning an Android UI used by millions

As the first Android developer of Photoroom, I knew I would have a lot of work to catch up with all the iOS app features as fast as possible. We did a lot in few months, and the first feedback and reviews on the Play Store were excellent! After six months, it was the perfect time to rethink the central part of the app: the editing view.

Create a better editing user experience 🧑‍🎨

Our main goal at Photoroom is to let our users create images for selling or having fun in the easiest possible way. Considering this, it’s safe to say that the user experience is our top priority. We decided to revamp the editing UI to give the user quick access to the main object features, like lighten a dress, changing the background color depending on the product colors, or quickly finding the perfect font for your title.

The thing is that when you have an app already downloaded and used by millions of users, you don’t want to mess up 🙃

Design & talks 🎨

The first step was to define how we could improve the editing process. To do that, we tested many different apps, asked for users’ feedback, selected the UI patterns that made sense for us, and created a Figma design with all our ideas. After some back and forth between the design & tech teams, we finally had our first design version ready!

With the help of Figma, our designer created a prototype to give us an idea of how the UI should work and how all components will interact together. Everything was ready to start prototyping the new UI.

MotionLayout to the rescue 🪄

Time to get your hands dirty! 🛠 What do we want here? A layout with a rendering view on the top (more precisely as a list view header), followed by a list of objects and actions. Ho, and yes, it should be animated too!

This is a perfect use case for a MotionLayout with two states:

  1. Extended: the rendering view will take around 50% of the screen height to allow the user to focus on his work.

  2. Collapsed: the rendering view will take around 30% of the screen height to let more space for the available editing actions.

How does this work? We want to start transitioning from the extended to the collapsed mode when the user scrolls. It becomes a bit more complicated when we add that the user should be able to reset the UI to the extended state when he wants (for example, by clicking on the rendering view or selecting an action).

Well, thanks to the MotionLayout, half of the work will be done quickly:

  • We create a MotionLayout scene with two ConstraintSet

<ConstraintSet android:id="@+id/scene_extended>
    <Constraint android:id="@+id/constraint_1" ... />
    <Constraint android:id="@+id/constraint_2" ... />
    <!-- Other constraints -->
</ConstraintSet>
<ConstraintSet android:id="@+id/scene_collapsed>
    <Constraint android:id="@+id/constraint_1" ... />
    <Constraint android:id="@+id/constraint_2" ... />
    <!-- Other constraints -->
</ConstraintSet>
  • Then, we add a Transition to animate the components between our two ConstraintSet

<Transition
    android:id="@+id/transition_from_extended_to_collapsed"
    app:constraintSetEnd="@id/scene_collapsed"
    app:constraintSetStart="@id/scene_extended"
    app:duration="200"
    app:layoutDuringTransition="honorRequest">

    <OnSwipe
         app:dragDirection="dragUp"
         app:touchAnchorId="@id/recycler_view"
         app:touchAnchorSide="top"
         app:onTouchUp="stop" />

</Transition>

Here’s the result:

One more thing to add: we want to let the user move from collapsed to extended states even if the RecyclerView isn’t scrolled at the top. That’s where things get a bit more complicated. To do that, we have to say goodbye to the transition element OnSwipe and start managing the transition progress ourselves. After some tests, the easiest and cleanest way we found was to add an OnDrawListener to the viewTreeObserver of the RecyclerView and do the math.

The first step is to manually compute and update the transition progress value by catching the scroll direction and scrollY distance from the top (precisely what OnSwipe was doing before). Then, we add two things:

  • A function to reset the transition to the expanded mode

  • A variable to keep in memory the starting scrollY value

With that, we will be able to re-start the expanded-to-compact transition whatever the scrollY value of our RecyclerView.

Let’s take a look at the result:

After one month of work and a lot of iterations, we were ready for the next step: user testing!

Time for tests 🧪

To have quick feedback and understand how users will behave with the new UI, we decided to launch few tests on usertesting.com. Even if the first batch of tests (3 users) was a bit disappointing (because they weren’t really involved), some key functionalities weren’t easy enough to find, like changing the background color.

Example of fast iteration changes we made after the first batch of users’ tests (from top to bottom):

  • Change the opacity and behavior of the back button (deselect the current object instead of closing the edit view)

  • Update the size of the buttons to fill the width, and increase background contrast

  • Add a quick color picker (which was accessible by the button Replace before)

In less than a day, we were able to make these changes and launch a new batch of tests. The feedback was way more positive! 🥳


Once we decided the new UI was ready to be deployed, we had to be sure it will perform at least as the previous UI. To monitor that, we used Firebase Remote Config to activate the new UI only for a small percent of our users and Amplitude to follow our users' behaviors:

The new UI performed around 5% better than the previous one

Conclusion & what’s next? 👀

With the appropriate tools and fast iterations cycles, we were able to get great feedback quickly and put in production a new UI which was a few weeks ago only a Figma prototype.

The fast iterations process allows us to test and publish new features every week and take decisions depending on how our users receive them.

We’ll continue to learn from our users.

Aurelien HubertSenior Android Engineer @ Photoroom
Bir sonraki mükemmel görselinizi tasarlayın

Bir sonraki mükemmel görselinizi tasarlayın

İster satış yapın, ister tanıtım yapın, ister gönderide bulunun; fikrinizi, öne çıkan bir tasarımla hayata geçirin.

Keep reading

Working smarter with AI-led qualitative analysis at Photoroom
Cori Widen
4 times faster image segmentation with TRTorch
Matthieu Toulemont
What's new in product: September 2023
Jeanette Sha
Photoroom acquires GenerateBanners and launches Visual Ads Automation—first-to-market GenAI engine for large-scale ad creatives
Lyline Lim
How we measured the CO2 emissions of our AI models at inference time
Matthieu Toulemont
We’re training a text-to-image model from scratch and open-sourcing it
Jon Almazán
Businesses need more threesomes, reveals market report
Aisha Owolabi
What's new in product: June 2024
Jeanette Sha
Tales from Photoroom Hackathon Nº3
Eliot Andres
Explore new Gen AI features coming soon to the Photoroom API
Udo Kaja