Natour
← Back to chapters

April 2025 - Easter

[Animation · Snackbar · UI · State Management] – Shaky Egg

textpost · published

Attachments

🎭 Scenario

You’ve been invited to help out with a quirky Easter app with digital shaking eggs. Your job is to bring a playful, dynamic egg to life. This egg has a mind of its own and responds to your taps, but only when it feels like it. Your motion designer friend had a vision of a fun, slightly mischievous egg, and now it’s up to you to code that behaviour.


🎯 Feature Goal

  • Create a full-screen UI with a periodically shaking egg that, when tapped, shows a snackbar with a time-dependent message.

  • All this feature does is automatically start an egg-shaking animation and play it until the user taps the egg. Once tapped, the egg stops shaking, and a snack bar is shown. After a few seconds, the egg starts shaking again until it is tapped.

📌 Requirements

  • Solid blue background (#0F1241)

  • Large egg in center of the screen

    • The egg should perform a continuous shaking animation

    • When tapped:

      • Egg should stop shaking

      • Show custom snackbar message with text: "You've hatched it!"

    • After a short delay of a random duration between four (4) and six (6) seconds, the egg should automatically start shaking again

    • Tapping the egg while it is not shaking should show a custom snackbar with text: "Easter egg not ready yet!"

  • The shaking animation is left up to you - it should resemble an egg shaking.

    • The Figma mockups include an example of the shaking behaviour (Accessible by tapping the play icon found at the top right in between your profile icon and the share button).

    • To the right are two more example GIFs that you can use for inspiration when creating the shaking animation 👉🏼

  • Two different custom snackbar UI components

    • A yellow and orange gradient shown when the shaking egg is tapped

    • A grey one shown when the idle egg is tapped


🤔 What's Allowed?

  • Standard Android/Jetpack libraries

  • No 3rd party libraries are allowed or would be required to complete this challenge

⚠️ What's NOT important for a valid submission?

  • The aim of this challenge is not to create an elaborate shaking animation; as long as it reasonably appears to be shaking, it will be accepted 👍🏼 We want to test your ability to work with Compose animations.

🧠 Disclaimer

  • This is not a full animation system or state machine challenge. The focus is on understanding animation timing, user interaction, and managing transient UI state with Jetpack Compose.


🏆 Submission & Rewards

  • A successful submission of this challenge via the /submit-challenge command on Discord grants you 100 XP. You can use it in any channel on Discord :)

  • A successful submission consists of these parts

    1. A link to a Gist showing your code for this challenge.

    2. Record a screen (max 10s) showing the egg shaking, then tap it to display a snackbar and stop the shaking. While the egg is idle, tap it again to show the alternate snackbar. Wait for the egg to start shaking again before ending the recording.

[Dialog · Animation · UI · State Persistence] – Egg Hunt Checklist

textpost · published

Attachments

🎭 Scenario

It’s Easter morning, and kids (and devs!) are on the hunt. Your task is to build a fun checklist UI to track which hidden Easter eggs have been found. You’re given a list of locations where there are eggs hidden and your app needs to help players mark them off one by one. Celebrate their success with a message of joy when they've found them all!


🎯 Feature Goal

  • Build a checklist UI using Jetpack Compose, where each egg location can be marked as found. Show an auto dismissable dialog when toggling a checkmark.

📌 Requirements

  • Single screen application

  • Title: "Egg Hunt Checklist"

    • Gradient color of yellow and orange

  • Subtitle: "Pick locations where you've found eggs"

  • Text beneath the subtitle that reflect the current amount of eggs found

    • "0/10 eggs found" / "4/10 eggs found"

  • A list of custom UI components

    • Each consists of:

      • A checkbox

      • Location text (e.g. "Inside the birdhouse")

    • When checkbox is ticked, UI component has a yellow and orange gradient background

    • When checkbox is unticked, UI component has a gray background

  • Show a custom dialog when any checkbox is toggled

    • Checkbox ticked

      • The progress bar at the top of the dialog starts from full and animates to 0% full. This animation takes four (4) seconds.

      • Yellow text that shows the number of seconds remaining of the progress bar animation just to the right of the progress bar

      • Easter bunny graphic

      • Text below the bunny graphic shows a random easter fact

        • Hint: A suggested implementation is shuffling the list of facts once and just loop through them during a single session, starting from the top when the bottom is reached.

      • Button with text "Dismiss"

        • On tap, dismiss the dialog

      • You can find a list of facts in the resources section to the right hand side 👉🏼

    • Checkbox unticked

      • The same progress bar and behaviour as described above

      • Text: "Oops, the egg rolled away!"

      • Egg graphic

      • Button with text "Dismiss"

        • On tap, dismiss the dialog

  • Progress of the ticked boxes must persits app restars

  • Button at the bottom of the list: "Reset"

    • On tap, clears all checkboxes and the saved state (i.e. restarting the app now will result in no checkboxes being ticked - a new session is created when "Reset" button is tapped)


🤔 What's Allowed?

  • Standard Android/Jetpack libraries

  • No 3rd party libraries are allowed or would be required to complete this challenge

⚠️ What's not important

  • The locats of the eggs can be of your own choosing, feel free to use the ones in Figma as well.

🧠 Disclaimer

  • This cheerful challenge isn’t just about checking boxes—it tests your state persistence skills and your ability to auto-dismiss dialogs as the player finds new eggs or loses them!

🏆 Submission & Rewards

  • A successful submission of this challenge via the /submit-challenge command on Discord grants you 100 XP. You can use it in any channel on Discord :)

  • A successful submission consists of these parts

    1. A link to a Gist showing your code for this challenge.

    2. Recording of thirty (30) seconds max showing the following:

      1. Start with no checkboxes ticked

      2. Tick item #4

      3. When dialog is shown, wait for it to dismiss

      4. Scroll to the bottom item and tick it

      5. Tap the dismiss button on the dialog

      6. Untick the bottom ticked list item

      7. Dismiss it by tapping outside the dialog's boundaries

      8. Kill the app and relaunch it

      9. Show that List item #4 is still ticked

[Clipboard · UI · State Management] – Clipboard Chickifier

textpost · published

Attachments

🎭 Scenario

Easter season is here, and your job is building a delightful tool for sending festive messages! This app lets users type their own text, and with a single tap, they can copy a "chickified" version—wrapped in emojis like 🐣 and 🐰—to paste anywhere they like. It’s a cheerful way to spread joy on chats and social media.


🎯 Feature Goal

  • Create a UI where users can type any message, transform it into a "chickified" version, and copy it to the clipboard. Also, include a curated list of pre-written messages for instant sharing.

📌 Requirements

  • No mockups are needed for this challenge

    • The look and feel of the UI is up to you

    • Just using standard Material 3 components will make this app look professional

  • Title text

    • This can be anything of your choosing - a suggestion is "Easter Messages Hub"

  • Textfield where user can enter text they want to "chickify"

    • Placeholder text: "Type something to Chickify!"

  • Button below the input textfield

    • Text: "Copy"

    • On tap, format the input text and formatting it to the following:

      • Input: "Hello World"

      • Output: "🐣🐰 Hello World 🐰🐣"

    • Formatted text must be saved to the device's clipboard

    • Show a toast confirming the text was successfully copied

      • The text shown is up to you

    • Disable the button when the text input is empty

  • Below the "Copy" button, show a list of prewritten text list items

    • You can find a list of pre-written messages in the Resources section 👉🏼

    • The on tap behaviour is the same as when the "Copy" button is tapped when there is input to format

      • Format message, show confirmation snackbar, and save formatted text to clipboard


🤔 What's Allowed?

  • Standard Android/Jetpack libraries

  • No other 3rd party libraries are allowed or would be required to complete this challenge

⚠️ What's not important

  • UI presentation won't prevent a valid submission as long as the app meets all other requirements listed above

🧠 Disclaimer

  • This charming little challenge helps you flex your state management and clipboard interaction skills.


🏆 Submission & Rewards

  • A successful submission of this challenge via the /submit-challenge command on Discord grants you 100 XP. You can use it in any channel on Discord :)

  • A successful submission consists of these parts

    1. A link to a Gist showing your code for this challenge.

    2. A screen recording (10s max) that shows the following:

      1. Input a fun message into the input text field

      2. Tap the copy button

      3. Navigate outside the app and use the device's paste command

      4. Return to your app and tap any of the preselected messages

      5. Redo the paste command outside the app

[Drag and Drop · Animation · UI · State Management] – Egg Basket Collection

textpost · published

Attachments

🎭 Scenario

It’s egg-hunting season, but this time you’re on basket duty! You’ve been hired by a quirky educational app that teaches kids (and let’s be honest—some adults too) the fine art of virtual tidying up. In this Easter-themed mini-game, a bunch of unruly eggs have staged a rebellion and are scattered all over the screen. Your job? Help users drag these mischievous little guys back where they belong—the basket. With every successful drop, the basket looks happier, and the mess gets smaller. It’s cleanup time!


🎯 Feature Goal

  • Build an interactive drag-and-drop interface where users move eggs into a designated basket “hot zone.” Upon successful drops, the basket image should update to reflect progress. Encourage good drops and discourage misses with visual and animated feedback.

📌 Requirements

  • Small egg basket graphic with egg counter to keep track of the amount of eggs already collected

    • Each successful egg dropped in the basket must increment this counter

    • You can find the mockups in the attachments section 👉🏼

  • Button at the top right of the screen

    • Text: "Restart" with leading icon

    • Disabled when there are no eggs collected yet

      • Background is a grey gradient color

    • Enabled when there is at least one egg collected

    • When tapped, empty the basket and place back all the eggs on their original places

      • Alternatively, you can randomise their placement, but it is not needed for a valid submission

  • Title text: "Easter Basket" at the top center of the screen, below the egg counter and reset button

  • Egg basket graphic

    • Placed at the bottom center of the screen

    • Should have an invisible radius around it which is referred to as the "hot zone"

      • When an egg is dropped inside this zone, it counts as a collected egg

      • If it is dropped outside this radius

        • The egg animates to its original position

          • Again, if you like - the egg can animate to a random position, but it is not needed for a valid submission

        • Show a standard Material 3 snackbar with the text: "🧺 Aim for the basket!"

    • When an egg is within the bounds of the "hot zone", the basket graphic should get a slight yellow glow to indicate that the user can safely drop the egg.

    • There are seven (7) different graphics for this basket, starting from an empty basket all the way to a basket with six (6) eggs in it

    • Each time an egg is dropped onto the basket

      • The graphic needs to update to reflect the new amount of eggs collected.

      • The egg needs to fade away

  • 6 Yellow eggs placed in the center of the screen at different locations

    • Eggs can be placed anywhere between the title and the bottom basket graphic

    • Feel free to adjust the sizes of the eggs as you see fit

    • An egg should be draggable when user performs a drag gesture

      • Once the egg is draggable, it receives a slight yellow glow around it.

  • Once the last egg is placed in the basket

    • Show a Material 3 toast with text: "You've collected them all!"


🤔 What's Allowed?

  • Standard Android/Jetpack libraries (Modifier.pointerInput with detectDragGestures will be useful here 🙂)

  • No other 3rd party libraries are allowed or would be required to complete this challenge

⚠️ What's not important

  • Exact placements of eggs on the screen


🏆 Submission & Rewards

  • A successful submission of this challenge via the /submit-challenge command on Discord grants you 200 XP. You can use it in any channel on Discord :)

  • A successful submission consists of these parts

    1. A link to a Gist showing your code for this challenge.

    2. A screen recording (20s max) that you collecting all eggs, dropping at least one of them outside the "hot zone" and then tapping the rest button once you've collected them all.

[Multi-step Flow · Navigation · UI · State Persistence] – Easter Checkout Flow

textpost · published

Attachments

🎭 Scenario

You’re designing a fully personalized Easter basket ordering experience for a boutique gift shop going digital. Customers can build their own baskets from scratch—choosing between sweet treats and playful toys—then customize every part of it. You’ve been asked to create a multi-step checkout flow that adapts based on the user’s choices, keeps progress visible at all times, and gracefully handles interruptions like accidental app closes or phone calls.


🎯 Feature Goal

  • Build a complete, multi-screen checkout flow that allows users to customize and order an Easter basket. Users can re-enter any part of the flow from a summary screen. ViewModels should handle state persistence with SavedStateHandle, and the flow should be resilient to process death.

📌 Requirements

  • The checkout flow consists of number of steps before reaching a summary screen

  • Each screen has a solid blue color background (#0F1241)

  • Step #1 screen

    • Custom UI Title with text: "Easter Checkout"

    • Text: "Pick the basket you want to collect"

    • Below it is two options: "Candy Basket" and "Toy Basket"

      • Tapping on either will move the user to step two of the checkout flow

      • Depending on which was tapped, step two will have a different selection to make

  • Step #2, #3, #4, and #5 screens

    • Top bar with back arrow and title "XXX Basket" (name depends on which was selected in Step #1

      • The back arrow takes the user back to the previous step

    • Material 3 progress bar filled to the % associated with the current step with text next to it "1/4"

      • Step #2 of 4 will fill the bar 50%

      • Step #2 of 5 will fill the bar 40%

    • Title for the selection will depend on what is currently being asked of the user. The exact text for each can be found on Figma.

      • You can find the mockups in the attachments section 👉🏼

    • Yellow text to indicate the amount of options the user can select

      • "3/5 selected"

      • This text is only visible when the user can make more than one selection

      • Value must update as the user ticks and unticks boxes

      • User should not be able to select more than the allowed amount for the Step # number

        • How you manage this is up to you. You can, for example, disable the "Next" button when the user selects more than they are allowed, or disable the other options once the max allowed selections are met.

    • Two buttons at the bottom of the screen

      • "Reset" clear all the user's selections on the current Step # screen

      • "Next" takes the user to the next screen

      • Both buttons are only visible when the user can make more than one selection

    • Each selection is in a vertical list with the item name and a checkbox to indicate if it is checked or not

      • Checkbox is only visible when the user can make more than one selection

      • Single-selection items are also center aligned

  • The summary screen

    • Top center title with text "Easter Checkout" same as the title in Step #1

    • Text below: "Your Easter basket summary"

    • Below the text is a list of the user's selections. Each represents a Step # where the user made a choice

      • When the user made no selections for a step then do not show a list item for that step

      • Edit icon at the far right

      • Tapping on any list item will take the user back to that Step #

        • When the user returns to Step #2, #3, or #4, the "Next" button text must change to "Done"

          • When the button is tapped, take the user back to the Summary screen with the updated selections

        • When the user taps to edit Step #1

          • Take the user back to Step #1 screen

          • If the user taps on the same basket type then each following step should show their previous selection which they can modify. Each step will have the "Next" button that takes the user through to the next step until they reach the summary screen again

          • If the user taps a new basket type then their selection can get reset and you can treat it as a fresh checkout flow session

      • "Done" button at bottom of the screen

        • Reset the checkout flow to the start

        • The current session and all its information can be cleared to start fresh

  • The user's checkout selection must be persisted to ensure a customer is not lost due to interruptions. Even after deliberately killing the application, the app must return to where the user left off in the checkout flow

    • Their past Step # selections must be saved

    • The current step they left at must be saved


🤔 What's Allowed?

  • Standard Android/Jetpack libraries

    • Shared Preferences or Data Store can help you persist state when app is killed

    • For process death, their is always SavedStateHandle 👀

  • No 3rd party libraries are allowed or would be required to complete this challenge

⚠️ What's not important

  • Screen transition animations

🧠 Disclaimer

  • This isn’t just a holiday-themed checkout—it’s a true test of your navigation architecture, state management, and multi-step flow design. You’ll learn how to reuse composables, handle complex branching, and persist progress across process death. It’s a realistic simulation of a mobile e-commerce experience—just with more chocolate eggs.


🏆 Submission & Rewards

  • A successful submission of this challenge via the /submit-challenge command on Discord grants you 300 XP. You can use it in any channel on Discord :)

  • A successful submission consists of these parts

    1. A link to a Gist showing your code for this challenge.

    2. A screen recording (30s max) where you:

      1. Tap candy basket on Step #1

      2. Select any wrapper on Step #2

      3. Select 4 of the candies

      4. Tap the reset button

      5. Tap the back arrow until you reach the Step #1 again

      6. Select the toy basket

      7. Select any option on Step #2 for the basket size

      8. Select the first 3 options in the list for the toys in Step #3 and tap next

      9. Select all for extras in Step #4 and tap next

      10. Choose any gift tag message

      11. On the summary screen edit Step #3

      12. On Step #3 screen, select the last 3 toy options in the list

      13. Kill the app

      14. Return to the app (it should open on Step #3)

      15. Tap the done button

      16. On the summary screen tap the done button