A Simple, yet beautiful, fab animation

Gauthama Nair
2 min readOct 26, 2020

The below fab animation is one that has fascinated me(Gmail compose like), it is simple and captivating. It acts like a tool tip and on scrolling down it shrinks down to a normal fab (Excuse the orange semi circular button popping in the middle of the screen, still figuring out how to hide this while recording a video)

What basically is observed is that there are two transitions present

  1. When we scroll down, the button shrinks
  2. When we scroll up, the button expands back again

When it comes to animation we are overwhelmed with options in android, and always are confused as to what goes where, what to use when trying to solve a particular animation problem.

The usual suspects are below with a one liner taken for when it is useful from the android dev summit 18 video

Motion Layout: Complex coordinated layout with gestures

Physics: Interruptible/ physics based animation with gesture

Transitions: Shared Element/Window content transition

Animated Vector drawable: Vector graphic animation

View Animations: Window animations

View Property Animator: Property of Views

Value animator: Custom animation on views

Object animator: General purpose property animation

The above animation is change in width of the view, basically either it increases(circle to stadium shape) or decreases(stadium shape to circle)

By their one line descriptions we see three of the above as being of interest, view property animator, value animator and object animator.

ViewPropertyAnimator is useful in translation, rotation, change in alpha and scaling animation problems, running them together with a pretty easy syntax. Since our problem would not fit in any of the above, this choice was discarded.

ObjectAnimator more or less works with the same set of properties as above, the properties that can be animated are listed here and hence discarded.

We are left with ValueAnimator , and changing width of a view requires a custom animation.

Show me some code

val anim =
ValueAnimator.ofInt(view.measuredWidth, END_WIDTH)
anim.duration = 200
anim.addUpdateListener { animation ->
view.layoutParams.width = animation?.animatedValue as Int
view.setLayoutParams(view.layoutParams)
}
anim.start()

The above code does it, we trigger an animation from current view(fab) width to end width(expanded/contracted) and change the layoutParams with width changed according to animated value.

Note

  1. We keep the y value of scrolling and trigger animation based on this
  2. Have used a button with left drawable and sufficient spacing as fab, so that when it contracts to a circle, only icon shows.

The entire code for this can be found here

That’s it we have achieved the above said animation

I am thankful that the office work I do, had me familiarize myself with these topics and rekindled the passion in me for animation/motion.

Do let me know, in case of queries/suggestions/or if more verbose explanation is required for this.

--

--