Application Design 2 -Task 3: Interactive Component Design & Development
xx.xx.2025 - xx.xx.2025 / Week 7 - Week 11
IAN CHOO XIN ZHE / 0369451
Application Design 2 / Bachelor of Design (Honours) in Creative Media
MIB
Task 3: Interactive Component Design & Development
Students will build upon the knowledge gained in Task 2 to create micro-interactions and animated micro-interactions for their app. This will greatly elevate the user experience of the app. The aim of this task is to get the students to explore and make creative decisions on the type of interactions they would want to integrate into their app.
To begin the development process, I first created the necessary blank pages that represent the core flow of my MVP (Minimum Viable Product). These pages include the Home Page, Game Description, Cart, Payment & Purchase, and Completion Page. Each of these screens plays a key role in shaping the user journey, from browsing games to completing a purchase. By setting up these foundational pages early, I was able to clearly visualize the structure of my app and ensure that all critical touchpoints were accounted for before diving into detailed UI and logic development.
My initial plan was to focus solely on building the UI first translating my designs from Figma into FlutterFlow. I began with the Home Page, as it sets the tone for the rest of the app and is typically the user’s first point of interaction.
At first, the process of learning how to use Rows, Stacks, and Columns in FlutterFlow was both time-consuming and confusing. The layout logic was quite different from what I was used to in traditional design tools. It was honestly frustrating at times, but I took the time to watch tutorials and also asked ChatGPT for guidance whenever I got stuck.
Over time, things started to click. I began to understand how these layout widgets worked together, and I was finally able to recreate the Home Page from my Figma design almost exactly within FlutterFlow. This breakthrough gave me a lot more confidence moving forward in the project.
Most of the layers in my Home Page were composed of images, and this was an intentional decision. Since many of these elements were purely visual with no interactive function, I realized that trying to recreate every single design detail natively within FlutterFlow would not only be time-consuming, but also potentially compromise the accuracy of the design. Instead, I chose to export certain visual elements from Figma as images, which helped preserve the exact look I wanted. This approach also significantly sped up the development process, especially for decorative elements or custom graphics that didn’t require dynamic behavior.
Next, I worked on the Cart Page, which turned out to be the fastest and easiest page to complete. Compared to the other screens, this one had fewer UI elements and less complexity, making the layout process much more straightforward. By this point, I was already familiar with the layout tools and structure, so building this page felt smooth and efficient.
After that, I moved on to the Payment Page. One of the key layout tools I had to work with here was the Stack widget, which initially took some time to fully understand. Positioning elements above one another while keeping everything aligned correctly was a bit tricky at first, but after some trial and error, I managed to make it work. By this stage, the overall workflow became much smoother, as I was getting more comfortable navigating FlutterFlow and building UIs more efficiently.
After completing the UI designs for all the pages, it was time to move on to implementing interactions and building the basic app flow. This meant connecting the pages together, setting up buttons to navigate between screens, and handling elements like promo code validation and dynamic text changes. It was a shift from purely visual design to more functional logic, and it marked the beginning of making the app feel like a real, working product.
I began by adding navigation actions to each screen making sure that tapping buttons would bring users to the correct next page in the MVP flow. I also set up the “back” arrows on each page to navigate to the previous screen, ensuring a smooth and intuitive experience. This step was important in turning my static UI into an interactive prototype. The storyboard shown above illustrates how all my screens are connected and how users would flow through the app from start to finish.
After setting up the cart UI, I moved on to adding interactivity — specifically, enabling the selection of a game and visually showing which game is selected. To achieve this, I used a selectedGameID
page state variable, which would store the ID of the currently selected game item. This was crucial for changing the border color of the selected item dynamically.
For the visual cue, I added a conditional border color to each container. If the item's ID matched the selectedGameID
, the border would turn blue to indicate selection. If not, it would remain transparent or default. This created a clear, user-friendly way to indicate which game was selected in the cart.
It took some trial and error to understand how to bind the container’s border color to the page state logic, but once I got it working, the system became very reusable and efficient. This process gave the Cart page more functionality and set the foundation for later interactions like applying promo codes or proceeding to checkout based on the selected item.
After implementing the selection logic for the cart items, I also needed to ensure that the "CHECKOUT" button behaved appropriately based on user interaction. The idea was to prevent users from proceeding without selecting a game, so the button had to remain greyed out and unclickable when no item was selected, and only become blue and interactive once a game was chosen.
To achieve this, I added a visibility condition tied to the selectedGameID
page state. When selectedGameID
was empty (i.e., no game was selected), the button's background color was set to a muted grey, and its action was disabled. This was done by wrapping the button action in a conditional check and also dynamically changing its style.
Once a user tapped on a game, the selectedGameID
would update, triggering the UI to re-evaluate the condition. The "CHECKOUT" button would then change to blue and become active, allowing the user to proceed to the next screen.
The Payment page was a major step in bringing real interactivity and logic into the app flow. While the UI itself was already in place, the core challenge lay in making the price update dynamically based on whether a valid promo code was entered, as well as showing a "Voucher Applied" tag once the discount was successfully detected.
I began by setting up a TextField where users could enter a promo code. I then created a Page State Variable called promoCode
to store whatever the user typed in. Using the “Update Variable on Change” option, the field was bound to this page state in real time. Then, I created another boolean Page State Variable called isPromoValid
that would be set to true only if the correct promo code (in this case, e.g. "STEAMWINTERSALES") was entered.
To update the price, I placed two text elements: one showing the original price and one showing the discounted price. I used visibility conditions so that the original price would be hidden and the discounted one would only appear if isPromoValid
was true. I applied the same logic to the “Voucher Applied” tag — it was set to only appear when a valid promo code was detected.
To make the logic work, I added an onChanged action to the promo input field. This triggered a conditional action: if the value typed matched the promo code, isPromoValid
would be set to true, and the discounted price (e.g. RM74 instead of RM84) would show. If not, the app would reset the page state and the discount would not apply.
One unexpected issue was that the default price text didn't show the "RM" prefix at first — it just showed numbers like "00" or "84". To fix this, I had to manually concatenate the text using a custom expression in the Text widget, like "RM " + price.toString()
so it always showed up correctly.
Through all this, I learned how FlutterFlow allows simple conditional logic to build meaningful and responsive experiences. It was especially rewarding to see the flow working smoothly: enter a promo code, see the new price appear, and get the instant visual confirmation with the voucher tag. It helped elevate the realism and polish of my MVP.
Walkthrough Video: https://drive.google.com/file/d/1O3s-WrsOI7CsH-6Wtq7-aZzabzNiiURH/view?usp=sharing
Reflection
Reflecting on this task, it’s been a challenging but incredibly rewarding journey. At first, I underestimated how tricky it would be to bring my UI designs from Figma into FlutterFlow. Learning how to structure layouts using Rows, Columns, and especially Stacks was frustrating I often had to redo pages several times. But with time, tutorials, and trial and error, I started to understand how things worked and got faster and more confident.
One of the most valuable parts of the process was learning how to handle page logic and interactivity. The Cart page taught me how to use page state variables to track selection, change borders, and conditionally enable the "Checkout" button. The Payment page pushed me further implementing a promo code feature, visual feedback, and dynamic pricing made me realize how much detail goes into making a simple user experience feel smooth and polished.
There were definitely tough moments. Some features were harder to replicate than expected, and I hit roadblocks that slowed me down. But every small breakthrough gave me more motivation. Overall, I learned to be patient, resilient, and solution-oriented. This experience gave me a deeper appreciation for how design and logic come together and boosted my confidence in turning ideas into functional prototypes.
Comments
Post a Comment