![]() |
VOOZH | about |
In this article, we are going to create a star shower using android property animation. We will create a slightly more involved animation, animating multiple properties on multiple objects. For this effect, a button click will result in the creation of a star with a random size, which will be added to the background container, just out of view of the top of that container. The star will proceed to fall down to the bottom of the screen by accelerating as it goes. the star will also rotate when it falls. A sample GIF is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Kotlin language.
๐ Star Shower in Android using Android Property AnimationStep 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language.
Step 2: We will need some local variables to hold the state.
val container = star.parent as ViewGroup
val containerW = container.width
val containerH = container.height
var starW: Float = star.width.toFloat()
Create a new View to hold the star as it is a VectorDrawable asset, make use of an AppCompatImageView, which has the ability to host that kind of resource. Create the star and add it to the background container.
val newStar = AppCompatImageView(this)
newStar.setImageResource(R.drawable.ic_star)
newStar.layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT)
Step 3: Sizing and positioning the star
We haven't defined the position of the image in the container, so itโs positioned at (0, 0) by default. We will fix it in this step.
(i) Set the size of the star. Modify the star to have a random size, from .1x to 1.6x of its default size. Use this scale factor to change the cached width/height values.
newStar.scaleX = Math.random().toFloat() * 1.5f + .1f
newStar.scaleY = newStar.scaleX
starW *= newStar.scaleX
starH *= newStar.scaleY
You have now cached the starโs pixel H/W stored in starW and starH:
๐ Image(ii) Now position the new star. It should appear randomly somewhere in between the left edge to the right edge horizontally. The below code uses the width of the star to position it from halfway of the screen on the left (-starW / 2) to halfway off the screen on the right (with the star positioned at (containerW - starW / 2).
๐ ImagenewStar.translationX = Math.random().toFloat() * containerW - starW / 2
Step 4: Creating animators for star rotation and falling
Itโs time to work on the animation. The star should rotate as it falls downwards. We can animate two properties together. The rotation will use a smooth linear motion (moving at a constant rate over the entire rotation animation), while the falling animation will use an accelerating motion (simulating gravity pulling the star downward at a constantly faster rate). So you'll create two animators and add an interpolator to each.
(i) First, create two animators, along with their interpolators:
val mover = ObjectAnimator.ofFloat(newStar, View.TRANSLATION_Y, -starH, containerH + starH)
mover.interpolator = AccelerateInterpolator(1f) // causes a gentle acceleration motion
val rotator = ObjectAnimator.ofFloat(newStar, View.ROTATION,
(Math.random() * 1080).toFloat()) // star rotates a random amount between 0 and 1080 degrees
rotator.interpolator = LinearInterpolator() //the rotation will proceed at a constant rate as the star falls
The mover animation is responsible for making the star โfall.โ It animates the TRANSLATION_Y property but causing vertical instead of horizontal motion. The code animates from -starH to (containerH + starH), which effectively places it just off the container at the top and moves it until itโs just outside the container at the bottom, as shown here:
๐ ImageStep 5: Running the animations in parallel with AnimatorSet
Now it is time to put these two animators together into a single AnimatorSet. It is basically a group of animations, along with instructions on when to run those animations. It can play animations in parallel.
(i) Create the AnimatorSet and add the child animators to it. The default animation time of 300 milliseconds is too quick for the falling stars, so set the duration to a random number between 500 and 2000 milliseconds, so that stars can fall at different speeds.
val set = AnimatorSet()
set.playTogether(mover, rotator)
set.duration = (Math.random() * 1500 + 500).toLong()
(ii) Once newStar has fallen off the bottom of the screen, it should be removed from the container. Set a simple listener to wait for the end of the animation and remove it. Then start the animation.
set.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
container.removeView(newStar)
}
})
set.start()
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the complete code for the activity_main.xml file.
Go to the MainActivity.kt file and refer to the following code. Below is the complete code for the MainActivity.kt file. Comments are added inside the code to understand the code in more detail.
Now, Run your application. You can click on the "STAR SHOWER" button multiple times, creating a new star and new animation each time.
Output:
Source code: Click Here