Play Button Coordinates

You can see our play-button is composed out of 2 triangles. In order to be compatible for morphing to the pause and stop-buttons a fourth point has to be defined on the triangles.

The point is not visible because it’s placed at (100,64) so it overlaps with another point.

play button upper part

We come up these four parts for the upper part

(44, 32)

(44, 64)

(100,64)

(100,64)

play button bottom part

Only one extra coordinate (44, 96) for the bottom part is required

(44, 96)

(44, 64)

(100,64)

(100,64)

Pause Button Coordinates

In order to obtain the full effect from play- to pause state. We have to rotate the pause button -90°. Otherwise we get another effect then intended.

wrong

correct

During the morphing we will then rotate it back to its correct position

The pause button

We come up these four parts for the upper part

(32, 40)

(32, 56)

(96, 56)

(96, 40)

We leave a 16px margin between the two pause rectangles.

The results for the bottom part coordinates

(32 88)

(32, 72)

(96, 72)

(96, 88)

Stop Button Coordinates

For the stop button the same rules apply as with the pause-button so we rotate the object to -90°.

the stop button

The correct coordinates for the upper part

(32, 32)

(32, 64)

(96, 64)

(96, 32)

The bottom part

(32, 96)

(32, 64)

(96, 64)

(96, 96)

Android Icon Animator

A few weeks ago while browsing r/androiddev I discovered Android Icon Animator by Roman Nurik. This marvelous tool allows you to just drag and drop any SVG and it will convert the SVG into the pathData.

Not only that but it allows you to see your animation before you even wrote one letter code. This let’s you wonder why Android Studio doesn’t come with tooling this easy. Sigh

Any who, Create a simple triangle using your favorite vector creating tool (ex. Illustrator or Inkscape) and add one extra point.

Export the vector as SVG. Opening the SVG in any text editor will reveal it’s commands.

My command looked similar to this.

M XX XX L XX XX L XX XX L XX XX Z

Play to Pause Animation

Let’s use the Android Icon Animator tool to aid us in to making our first animation.

Replace the coordinates from the command above with the coordinates we found in previous step.

I recommend you to place this pathData in your strings.xml file to keep things tidy.

<!-- Play Icon -->

<string name="play_icon_upper_path_data">M 44 32 L 44 64 L 100 64 L 100 64 Z</string>

<string name="play_icon_bottom_path_data">M 44 96 L 44 64 L 100 64 L 100 64 Z</string> <!-- Pause Icon -->

<string name="pause_icon_upper_path_data">M 32 40 L 32 56 L 96 56 L 96 40 Z</string>

<string name="pause_icon_bottom_path_data">M 32 88 L 32 72 L 96 72 L 96 88 Z</string>

Click on the icon and create a new group, name it: parts. In the parts-group create two more groups and name them: upperpart and bottompart.

Your structure should now look like this

In the upperpart-group create a path named upper.

In the bottompart-group create a path named bottom.

You should now see your vector appear on screen.

Click the New animation button.

Name your animation play_to_pause and leave the default duration at 300 ms.

Click the upper path and click on the little stopwatch logo, select pathData.

Change the toValue to the pause-pathData.

Repeat this step for the bottom path.

Your animation is almost done.

Click on the stopwatch icon for the parts group. Click on rotation and change the toValue to 90° degrees.

You can now use the slider to see the animation in action as it will render on Android.

Use the export function to generate your initial VectorDrawable and the chosen animations.

The export function is quite messy as it returns the animation in one XML file.

I extracted everything to the correct folders for maximum readability and re-usability.

Inside of the drawable folder paste the play_icon.xml which is our VectorDrawable

<vector

xmlns:android="http://schemas.android.com/apk/res/android"

android:width="128dp"

android:height="128dp"

android:viewportWidth="128"

android:viewportHeight="128">

<group

android:name="@string/play_icon_group_parts"

android:pivotX="64"

android:pivotY="64"

android:scaleX="1"

android:scaleY="1">



<group android:name="@string/play_icon_group_top">

<path

android:name="@string/play_icon_top_path_name"

android:pathData="@string/play_icon_upper_path_data"

android:fillColor="@android:color/black"

android:strokeLineCap="butt"

android:strokeLineJoin="miter"

android:strokeMiterLimit="10"/>

</group>

<group android:name="@string/play_icon_group_bottom">

<path

android:name="@string/play_icon_bottom_path_name"

android:pathData="@string/play_icon_bottom_path_data"

android:fillColor="@android:color/black"

android:strokeLineCap="butt"

android:strokeLineJoin="miter"

android:strokeMiterLimit="10"/>

</group>



</group>

</vector>

Make a play_to_pause_animation.xml which will be our actual AnimatedVectorDrawable

<?xml version="1.0" encoding="utf-8"?>

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"

android:drawable="@drawable/play_icon">



<target

android:name="@string/play_icon_group_parts"

android:animation="@animator/rotate_90_animation"/>



<target

android:name="@string/play_icon_top_path_name"

android:animation="@animator/upper_play_to_pause_animation"/>



<target

android:name="@string/play_icon_bottom_path_name"

android:animation="@animator/bottom_play_to_pause_animation"/>

</animated-vector>

The AnimatedVectorDrawable references the play_icon.xml and applies all the animation on the different parts

These animations are stored in the animator folder

For example the rotate_90_animation.xml animation

<?xml version="1.0" encoding="utf-8"?>

<objectAnimator

xmlns:android="http://schemas.android.com/apk/res/android"

android:duration="@integer/animation_duration"

android:interpolator="@android:anim/accelerate_decelerate_interpolator"

android:propertyName="rotation"

android:valueFrom="0"

android:valueTo="90"

android:valueType="floatType"/>

If you want to check out the full source code you can take a look at the repository on Github.

Custom View

Now our radio player app is able to stream ondemands and live radio.

That means we have two possible states the icon can animate to.

It also means we can animate back to the play icon when a stream is stopped or an ondemand was paused.

I decided to make a custom FloatingActionButton that does just that.

Add the FloatingActionButton to your layout and chose your mode with app:mode. You have the option between playToPause and playToStop.

<be.rijckaert.tim.animatedvector.FloatingMusicActionButton

android:src="@drawable/play_to_pause_animation"

android:layout_width="wrap_content"

app:backgroundTint="@color/colorAccent"

app:mode="playToPause"

android:layout_height="wrap_content" />

You can change the behavior dynamically by calling