When I started my journey in the Flutter world, I have learned the basic UI concepts just enough to build a simple application. State management, code structure, architecture, appliance of OOP design patterns — these topics are more interesting to me, so I have dived deeper into them. However, the majority of developers choose Flutter for its UI capabilities.
There are lots and lots of tutorials, articles out there on how to make custom UIs, applications using Dart + Flutter, but the majority of them covers only the HOW part (how to implement a specific component, animation, etc.), but usually the WHY part (why is it implemented in a certain way) is left somewhere else. This article covers the whole thought process on how to convert the design into code: explains HOW to do it and WHY it is done like this. There is a lot to cover, so brace yourself!
Table of Contents
- Flutter Design Challenge rules
- The Design Challenge: Onboarding Concept
- Design analysis 101
- Analysing static design components
- Analysing motion design
- Summary
- Your contribution
Flutter Design Challenge rules
Pure Dart + Flutter
No additional frameworks or third-party libraries could be used, only the Dart programming language, its features and Flutter SDK.Clean code
Even though it is just a design challenge and not a complete mobile application, the code should remain clean and maintainable by keeping consistent and clear project source tree, splitting code into separate widgets/components, reusing code, extracting general parameters, etc.The implementation (final result) could be less than 100% accurate
Design elements/components (both static and dynamic) should be implemented as provided in the design concept. However, their parameters could be adjusted if there is a valid reason, e.g. components’ dimensions could be changed to fit them on the mobile device screen. Also, some design assets (images, icons, etc.) could be replaced by similar ones or even skipped if they do not have a major impact on the design.Have fun!
The Design Challenge: Onboarding Concept
Here is the Design Challenge we will implement using Dart + Flutter:
It is an onboarding design concept by Yoonuch Chayhet posted on Dribbble.
Well, a lot is going on here… But it won’t be a challenge otherwise, right?
Design analysis 101
The design analysis consists of two parts:
Analysing static design components
In general, the easiest part of the design which could be implemented using Flutter is static design elements — cards, text, icons, buttons, form components, you name it. These components could change their properties (e.g. colour, dimensions, opacity) over time using animations/transitions, but the content remains static nonetheless. Hence, it is relatively simple to implement the general layout of the design using Flutter, its layout system and pre-defined widgets.Analysing motion design
In my opinion, this part is more complex than the previous one. To implement the motion design, you must identify various aspects: components and their properties which are affected by animations, the duration of animation(s) and intervals when a certain animation should start/stop, etc. Flutter provides a wide variety of widgets to work with animations and transitions (so-called implicit animations), but sometimes, especially when the motion design is more complex, you need to implement some custom ones explicitly.
Having these basics in mind, we can dive deeper into the analysis part and deconstruct the design into separate elements which could be implemented individually!
Analysing static design components
* Onboarding screen
Logo (1)
Since the same logo is used in the login screen as well, it makes sense to create a separate component for it.
Header (2)
The header consists of the logo component and a skip button. When the skip button is pressed, the screen changes to the Login screen.
Icon container (3)
As you can see in the picture, the same container is used for all the icons in the light card (only its size is different). Hence, the container (to be more specific, the white circle around the icon) should be extracted to a separate component.
Text column (4)
A combination of the title and description text elements which are centred horizontally. The content is different in each onboarding page.
Stacked cards (5)
This component consists of two cards: a bigger one (dark blue) and a smaller one (light blue) which is placed on top of the bigger one. Both of these cards have their content that is different in each onboarding page. Also, the layout of this component depends on the current onboarding page:
As you can see, onboarding pages 1 and 3 have the same stack structure where the light card is placed at the bottom of the dark card while in the second onboarding page the light card is placed at the top.
Onboarding page (6)
When the current onboarding page changes, components in this area changes as well. Therefore, it makes sense to wrap stacked cards and text column components by a container — onboarding page component.
“Next page” button (7)
A simple circular icon button. When the button is pressed, the current onboarding page changes. If it is the last onboarding page then the onboarding screen changes to the Login screen.
Current page indicator (8)
Shows how many onboarding pages are available. Also, the indicator colour changes based on the current onboarding page.
* Login screen
Logo (1)
The same logo component as in onboarding screen, just with a different size and colour.
Header (2)
The header consists of a logo component, title and subtitle text elements which are aligned to the left of the screen.
Curves (3)
A graphical element containing two curves of a different colour. How difficult could it be to implement, right? Boy oh boy, never have I been so wrong…
Input field (4)
An input field which consists of an icon and a placeholder text. All the input fields are of the same size.
Button (5)
A simple button component. As you can see in the picture, buttons are of a different colour (both background and text), also the “Continue with Google” button contains a colourful Google icon. All the buttons are of the same size.
Login form (6)
All the input fields and buttons belong to the same form, so it makes sense to wrap them by a container — the Login form component.
Analysing motion design
Let’s slow down the animations and then analyse them step by step.
* Onboarding page transition
The transition consists of three separate animations:
Cards’ slide transition
The transition itself is simple — cards slide out of the screen to the left and then slides back in from the right, both of the cards start and end their transition at the same time. However, a short note here is that the smaller card ”slides” faster than the bigger one.Text column crossfade animation
One text fades out and the other one appears at the same time — just a basic crossfade animation.Current onboarding page indicator’s rotate animation
The indicator rotates 360°. Just one small detail worth mentioning is that going from the onboarding page number 1 to 2 the indicator rotates clockwise, going from 2 to 3 — counterclockwise.
If we consider all of these animations as a single transition (and we do!), we need to identify when a certain animation starts/ends. For better understanding, I always recommend to draw a simple diagram to visualise all the steps of the transition:
Just in a single glance at the diagram, it is clear when a certain animation should start/end, which animations overlap with each other and what’s the whole duration of the transition — I cannot stress enough how helpful these details would be in the implementation part!
* Ripple effect
A very nice transition effect when a circle starts growing its size from the centre of the “Next page” button until the whole screen is filled. The duration of this transition — 400ms.
* Login screen transition
The transition consists of three separate animations:
- Header text fade-slide transition
- Graphical element/curves transition
- Form elements fade-slide transition
Transitions 1 and 3 are the same, just the amount of components differ: for the first transition two elements appear (title and subtitle text elements) while for the third transition — 5 different form components appear on the screen. Also, I have noticed, that even though these elements appear at the same time, it looks like some elements “slide” from a little bit further than the other ones, hence their velocity looks a little bit higher. As a result, we have that smooth transition when components push themselves bottom-up — take a look at how login form elements appear, you will get the idea.
But now we get to the fun part — curves transition. One of the possible ways to make it work is to have two separate curves (blue and grey) and change their dimensions, top/bottom edge positions for both curves over time. That’s quite a lot of properties changing in a single transition. But we can simplify this by looking at this problem from a different angle. Literally, from a different angle (pun intended):
Let’s say that the login page consists of 4 different layers stacked on top of each other. Now we cut the bottom of each layer (except the last one) and stack them again. As you can see, we get the result which is very similar to the login screen.
Ok, now we can adjust this a little bit: let’s cut the top white layer in a curve — we get the top edge of the blue curve, cut the blue layer in a curve — the top edge of the grey curve, cut the grey layer in a curve — that’s the top edge of the white login form’s background. And, voilà, that’s our login screen.
You could ask: how this additional complexity of layers even help? Well, instead of several different parameters changing during the transition, now we have only one for each layer and that’s the bottom edge’s offset from the final position. In simple words, during the transition, the bottom edge of each of the top three layers slides from the bottom of the screen to its final position — only one specific (offset) parameter is changing per animation, that’s it!
Finally, let’s create the diagram for the login screen transition as well:
Seems like the analyse part is done and now we are ready to implement the design in Flutter!
Summary
That's it for the analysis part. If you can't wait to see the implementation details, check out the article on Medium or wait for the next part to be published on dev.to!
Edit: Part 2.
Your contribution
💖 or 🦄 this article to show your support and motivate me to write better!
💬 Leave a response to this article by providing your insights, comments or wishes for the next topic.
📢 Share this article with your friends, colleagues in social media.
➕ Follow me on dev.to or any other social media platform.
⭐ Star the Github repository.
Top comments (0)