Android Native - Animate View Along Path - Part 2

dimitrilc 1 Tallied Votes 41 Views Share

Introduction

Welcome to part two of the tutorial. Let us continue to learn how to animate views along a Path. Part one can be found here.

Important Coordinates

Both the sun and the moon in our app can occupy any one of the three important coordinates on the screen:

  • Active planet coordinate: this the is (x,y) coordinate of the sun or the moon when the animation is complete.
  • Hidden coordinate on the right bound: this is the coordinate of the sun or the moon that is setting (disappearing from view).
  • Hidden coordinate on the left bound: this is the coordinate of the sun or the moon that is rising (appearing into view),
  • quadTo() control coordinates: this is the coordinate that controls the curve of the Path drawn by the quadTo() method. I felt that it was important for the sun and the moon to rise/fall on a curve, which looks much more organic than flying straight in from the left or right side.

To be able to get these coordinates correctly, we can get them after the views have been drawn by the system. In MainActivity, add the instance properties below.

// Size is added to x,y coordinates to make the planet go off screen
private var planetSize = Pair(0, 0)

// Location of planet when it is shown on screen
private var activeXY = Pair(0f, 0f)

// Location of planet when hidden outside left or right bounds
private var hiddenLeftXY = Pair(0f, 0f)
private var hiddenRightXY = Pair(0f, 0f)

// Control points for quadTo() function
private var risingControlXY = Pair(0f, 0f)
private var settingControlXY = Pair(0f, 0f)

In onCreate(), before the button’s on-click listener call, add the code below to initialize the coordinates.

// Initiates coordinates after the sun is drawn
sun.post {
   planetSize = Pair(sun.width, sun.height)
   activeXY = Pair(sun.x, sun.y)
   hiddenLeftXY = Pair(
       0f - planetSize.first,
       activeXY.second + planetSize.second
   )
   hiddenRightXY = Pair(
       activeXY.first * 2 + planetSize.first,
       activeXY.second + planetSize.second
   )
   risingControlXY = Pair(
       activeXY.first - activeXY.first * 0.75f,
       activeXY.second
   )
   settingControlXY = Pair(
       activeXY.first + activeXY.first * 0.75f,
       activeXY.second
   )
}

Rising And Setting Paths

Now that we have the important coordinates to create our Path, let us create the rising and setting paths for our planets. In the on-click listener, add the code below.

// Both sun and moon can use this animator
// Animates the planet setting
val settingPath = Path().apply {
   moveTo(activeXY.first, activeXY.second)
   quadTo(
       settingControlXY.first,
       settingControlXY.second,
       hiddenRightXY.first,
       hiddenRightXY.second
   )
}

// Both sun and moon can use this animator
// Animates the planet rising
val risingPath = Path().apply {
   moveTo(hiddenLeftXY.first, hiddenLeftXY.second)
   quadTo(
       risingControlXY.first,
       risingControlXY.second,
       activeXY.first,
       activeXY.second
   )
}

Animate Along A Path

We can set a View’s x and y using ObjectAnimator. Add the code below inside the on-click listener.

// Animates the sun rising or setting
val sunAnimator = ObjectAnimator.ofFloat(
   sun,
   "x",
   "y",
   if (isNight) risingPath else settingPath
)

// Animates the moon rising or setting
val moonAnimator = ObjectAnimator.ofFloat(
   moon,
   "x",
   "y",
   if (isNight) settingPath else risingPath
)

Last but not least, add these Animators into the AnimatorSet.

AnimatorSet().apply {
   // Play animations together
   playTogether(
       containerAnimator,
       cloudAnimator,
       sunAnimator,
       moonAnimator,
   )

   duration = 2000L
   start()
}

Play Animations Together

The code we have so far set up the animations to play together. Play the animation now and the app should behave like the animation below.

Daniweb_animated_day_night.gif

Play Animations Sequentially

If you would like, you can also play the animations sequentially.

           AnimatorSet().apply {
               // Play animations separately
               playSequentially(
                   containerAnimator,
                   cloudAnimator,
                   sunAnimator,
                   moonAnimator
               )

               // Play animations together
/*                playTogether(
                   containerAnimator,
                   cloudAnimator,
                   sunAnimator,
                   moonAnimator,
               )*/

               duration = 2000L
               start()
           }

Daniweb_animated_day_night_sequential.gif

Summary

We have learned how to animate a View along a Path in this tutorial. The full project code can be found at https://github.com/dmitrilc/DaniwebCombineAnimationsAnimatorSet.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.