Some time ago Twitter presented Hearts – replacement for star icons, with modern delightful animation of their state change.
— Twitter (@Twitter) November 3, 2015
While heart symbol is more universal and expressive, today we’ll try to reproduce new animation for alternative reality, using old, star icon. Effects of our work will look like this (and it’s bit faster than animated gif):
While the easiest way for implementing this (and original heart) animation would be to use Frame Animations, we’ll try to implement it with more flexible solution – by drawing it by hand and animating with ObjectAnimator. This post will be just a quick overview, without deep technical details.
We’ll create new View named
LikeButtonView which will be built on top of FrameLayout which hosts three child views – CircleView showing circle below star icon, ImageView (with our star) and DotsView presenting dots floating around our button.
This view is responsible for drawing big circle below star icon. It could be implemented easier (via xml and
<shape android:shape="oval">) but in this case we should care about background color below our button.
Our implementation draws circle(s) on canvas:
Each frame starts from clearing whole canvas by drawing color with CLEAR mode. Then view draws inner and outer circle based on given progress (separately for both of them).
Inner circle uses mask paint defined in this way:
It means that our circle will create transparent hole inside our outer circle.
Our View uses
tempBitmap defined here:
We need to do this for true transparency. Otherwise our inner circle would show window color instead.
For skilled eye there is one more thing – our outer circle changes its color based on current progress. It’s done by ArgbEvaluator class which transforms two colors based on given fraction:
The rest of
CircleView code is just an implementation. Full source code can be found here: CircleView.
This view will draw dots floating around our star icon. Same as
CircleView it will use
onDraw() to do this:
Dots are drawn based on
currentProgress backed by math and honestly, it’s hard to point something interesting here (from Android SDK perspective). Instead, here are a couple math-related things:
- Dots are arranged on invisible circle – their position is determined by:
what means: set dot on every
OUTER_DOTS_POSITION_ANGLE (51 degrees).
- Each dot has its own color animation:
It means that dot color is animated between 3 values in ranges: [0, 0.5) and [0.5, 1]. One more time we use
ArgbEvaluator to make it smooth.
The rest is pretty straightforward. Full source code of this class is available here: DotsView
Our final views group is composed from
We used Merge tag which helps to eliminate redundant view groups.
LikeButtonView itself is
FrameLayout so there is no need to have it twice.
Our final view animation is composed from a few smaller ones, played together by
And it’s all about proper timings and interpolators.
LikeButtonView also reacts on touch event (with scale animation):
And… That’s all. 😃 As you can see, there is no magic here, but the final effect can be very nice. So what now? Let’s make our apps even more delighful.
Full source code of described project is available on Github repository.