A few days ago, on Chinese Valentine’s Day, the streets were full of dog food, and even movie seats were popular, which were screened by single dogs and love wipers. This effect looks good, implementation is not difficult, decided to copy a wave.

Before we start, here are the renderings:

Details of the split

1. Each view falls from the top to the bottom and then disappears from the bottom.

2. The initial random position of each view on the X-axis begins to fall.

3. Each view has a random initial Angle and rotates during falling.

4. Each view initially falls at a random height, but eventually disappears from the bottom.

Implementation steps

First, I implement a view drop process, and here I have a built-in property animation.

Private float rainyFraction; public void startAnimator() { if (objectAnimator == null) { objectAnimator = ObjectAnimator.ofFloat(this, "rainyFraction", 0, 1); objectAnimator.setDuration(6000); } objectAnimator.start(); } public float getRainyFraction() { return rainyFraction; } public void setRainyFraction(float rainyFraction) { this.rainyFraction = rainyFraction; invalidate(); }Copy the code

Then override the onSizeChanged and onDraw methods to get the width and height of the entire view and draw the bitmap

Float dx. @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); width = w; height = h; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); // reset matrix, must be reset otherwise matrix. Reset (); Dx = width / 2; float dy = height * rainyFraction; matrix.postTranslate(width/2, dy); canvas.drawBitmap(bitmap, matrix, paint); canvas.restore(); }Copy the code

With the effect of falling, now consider the random position in the X-axis. The method to obtain the initial X-axis position is as follows:

Float dx = (float) ((width-imagesize) * math.random ()); float dx = (float) ((width-imagesize) * math.random ());Copy the code

PostRotate (degrees, px, py) can be used to calculate the initial Angle of the matrix

Int Angle = (int) (math.random () * 360); int Angle = (int) (math.random () * 360); PostRotate (180 * rainyFraction + Angle, imageSize / 2 + dx, imageSize / 2 + dy); postRotate (180 * rainyFraction + Angle, imageSize / 2 + dy);Copy the code

Finally, the calculation of random initial height is also simple

// Set the maximum height from the top to its own height, get a random value. float tempHeight = (float) (height * Math.random()); MaxHeight = math. Max (tempHeight, maxHeight); maxHeight = math. Max (tempHeight, maxHeight);Copy the code

Ok, so we’re done with a graph down here. Next is the effect of multiple images. How do I do that? The for loop! Here, I prepared three lists to save the corresponding initial X position, Y position and initial Angle, look at the code:

public void initCount() { widthArr.clear(); heightArr.clear(); angles.clear(); for (int i = 0; i < num; I++) {widtharr.add ((float) ((width-imagesize) * math.random ())); float tempHeight = (float) (height * Math.random()); // Random height from the top, is negative. The imageSize is added to ensure that the heightarr. add(-(imageSize + tempHeight)) comes down from the top; maxHeight = Math.max(tempHeight, maxHeight); // angles. Add ((int) (math.random () * 360)); }}Copy the code

These values are also used for loop in the onDraw method

for (int i = 0; i < num; I++) {// reset matrix, must be reset otherwise superimposed if (num! = widthArr.size()) { break; } matrix.reset(); // Current height = random initial height (negative) + (Height of view + height of highest dog == height of entire animation) * coefficient // Plus 2 * imageSize to ensure that dog heads fall out of the bottom float dy = heightArr.get(i) + (maxHeight + height + 2 * imageSize) * rainyFraction; matrix.postTranslate(widthArr.get(i), dy); PostRotate (angles. Get (I) + 180 * rainyFraction, imageSize / 2 + widtharr.get (I), imageSize / 2 + dy);  canvas.drawBitmap(bitmap, matrix, paint); }Copy the code

Finally, use RainyView in the activity

rainyView.initCount();
rainyView.startAnimator();
Copy the code

The completion of this effect ends here.

Write in the last

This is the GitHub address single dog Rain, and the complete code can be forked down from above. Give a star if you like. Thank you.

By the way, the effect of this drop is very rough, haha. And the speed of falling is not calculated, the speed of each view is the same. But that doesn’t matter, the important thing is to learn the essence of it.