Android Attribute Animation

What is attribute animation?

Property animation can be implemented by directly changing the properties of View. For example:

  1. The effect of moving the View is achieved by constantly changing the coordinates of the View.
  2. By constantly changing the background of View to achieve the effect of background gradient of View;
  3. The effect of deforming the View is achieved by constantly changing the width of the View.
  4. ...

Thus, using attribute animation can handle almost any animation effect involving View.

actual combat

Specific details are not much to say, the corresponding online tutorials are also many. This blog is mainly to achieve the effect similar to the American Troupe take-out shopping cart.

Analysis

Firstly, the details of cart animation are analyzed: during the sliding process, the cart moves to the right until half of the cart hides to the right; while the finger stays in the screen, the cart hides to the right; when the finger leaves the screen, the cart moves back after a certain time.

The above animation details are closely related to the rolling events of RecycleView, so animation should be implemented in the rolling events of RecycleView.

Realizing Basic Layout

The blue image above is both the View we are dealing with.

Add scrolling events to RecycleView

Next, add a scroll event to RecycleView, and the image disappears when it slides or flies, and displays when it stops sliding.

 1 // to rv Add scrolling events
 2 rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
 3     @Override
 4     public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
 5         switch (newState) {
 6             case RecyclerView.SCROLL_STATE_DRAGGING:// Rolling
 7             case RecyclerView.SCROLL_STATE_SETTLING:// Flying
 8                 iv.setVisibility(View.GONE);
 9                 break;
10             case RecyclerView.SCROLL_STATE_IDLE:// Stop scrolling
11                 iv.setVisibility(View.VISIBLE);
12                 break;
13         }
14     }
15 });

Design sketch:

Animation of disappearance

According to the above figure, we can see that the trigger time is basically no problem, the next thing to do is to make the disappearance not abrupt, plus the disappearance of the animation.

The essence of the disappearance is that the x coordinates of the View go from the current position to the right until they are half hidden. Let's achieve this effect:

 1 // Basic properties of vanishing animation (from iv Current x The coordinates go up to the right half of the screen.
 2 disappearAnimator = ValueAnimator.ofFloat(iv.getX(), (float) (Utils.getScreenWidth(this) - iv.getWidth() / 2.0));
 3 disappearAnimator.setDuration(400);// Animation duration
 4 disappearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 5     @Override
 6     public void onAnimationUpdate(ValueAnimator animation) {// Value Update events
 7         float curValue = (float) animation.getAnimatedValue();
 8         iv.setX(curValue);
 9     }
10 });
11 
12 // to rv Add scrolling events
13 rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
14     @Override
15     public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
16         switch (newState) {
17             case RecyclerView.SCROLL_STATE_DRAGGING:// Rolling
18             case RecyclerView.SCROLL_STATE_SETTLING:// Flying
19                 disappearAnimator.start();
20                 break;
21             case RecyclerView.SCROLL_STATE_IDLE:// Stop scrolling
22                 iv.setVisibility(View.VISIBLE);
23                 break;
24         }
25     }
26 });

However, it is found that in fact the animation is like this:

It was found that he moved from the far left to the far right, which was not in line with our needs.

After debugging, it was found that iv had not been initialized at onCreate, so the width and height as well as coordinates could not be obtained. So the coordinates and width obtained are all 0.

So you can get the coordinates and width of iv in the scrolling event. The changed code is as follows:

 1 // to rv Add scrolling events
 2 rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
 3     @Override
 4     public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
 5         // Obtain iv Coordinates and width and height
 6         if (0 == originX) {
 7             originX = iv.getX();
 8             ivWidth = iv.getWidth();
 9         }
10 
11         switch (newState) {
12             case RecyclerView.SCROLL_STATE_DRAGGING:// Rolling
13             case RecyclerView.SCROLL_STATE_SETTLING:// Flying
14                 // Basic properties of vanishing animation (from iv Current x The coordinates go up to the right half of the screen.
15                 if (disappearAnimator == null) {
16                     disappearAnimator = ValueAnimator.ofFloat(originX, (float) (screenWidth - ivWidth / 2.0));
17                     disappearAnimator.setDuration(400);// Animation duration
18                     disappearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
19                         @Override
20                         public void onAnimationUpdate(ValueAnimator animation) {// Value Update events
21                             float curValue = (float) animation.getAnimatedValue();
22                             iv.setX(curValue);
23                         }
24                     });
25                 }
26 
27                 disappearAnimator.start();
28                 break;
29             case RecyclerView.SCROLL_STATE_IDLE:// Stop scrolling
30                 iv.setVisibility(View.VISIBLE);
31                 break;
32         }
33     }
34 });

The effect is as follows:

Realize the animation that appears

Now that the disappeared animation has been realized, the animation that appears is not difficult. The essence of this is that the x coordinates of the View move from the right half to the original position.

 1 case RecyclerView.SCROLL_STATE_IDLE:// Stop scrolling
 2     // Basic attributes of animation (from the right half of the screen to the original position)
 3     if (appearAnimator == null) {
 4         appearAnimator = ValueAnimator.ofFloat((float) (screenWidth - ivWidth / 2.0), originX);
 5         appearAnimator.setDuration(400);// Animation duration
 6         appearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 7             @Override
 8             public void onAnimationUpdate(ValueAnimator animation) {// Value Update events
 9                 float curValue = (float) animation.getAnimatedValue();
10                 iv.setX(curValue);
11             }
12         });
13     }
14 
15     appearAnimator.start();
16     break;

The results are as follows:

However, it was found that the animation would conflict if frequent sliding pauses occurred, so some judgments need to be made. If the animation is running, the animation will not be restarted. The modified code is as follows:

 1 switch (newState) {
 2     case RecyclerView.SCROLL_STATE_DRAGGING:// Rolling
 3     case RecyclerView.SCROLL_STATE_SETTLING:// Flying
 4         // Basic properties of vanishing animation (from iv Current x The coordinates go up to the right half of the screen.
 5         if (disappearAnimator == null) {
 6             disappearAnimator = ValueAnimator.ofFloat(originX, (float) (screenWidth - ivWidth / 2.0));
 7             disappearAnimator.setDuration(400);// Animation duration
 8             disappearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 9                 @Override
10                 public void onAnimationUpdate(ValueAnimator animation) {// Value Update events
11                     float curValue = (float) animation.getAnimatedValue();
12                     iv.setX(curValue);
13                 }
14             });
15         }
16 
17         // If the vanishing animation has not yet started to execute and iv If the location is in the original position, the execution will occur.
18         if (!disappearAnimator.isStarted() && originX == iv.getX()) {
19             disappearAnimator.start();
20         }
21         break;
22     case RecyclerView.SCROLL_STATE_IDLE:// Stop scrolling
23         // Basic attributes of animation (from the right half of the screen to the original position)
24         if (appearAnimator == null) {
25             appearAnimator = ValueAnimator.ofFloat((float) (screenWidth - ivWidth / 2.0), originX);
26             appearAnimator.setDuration(400);// Animation duration
27             appearAnimator.setStartDelay(700);// delay time
28             appearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
29                 @Override
30                 public void onAnimationUpdate(ValueAnimator animation) {// Value Update events
31                     float curValue = (float) animation.getAnimatedValue();
32                     iv.setX(curValue);
33                 }
34             });
35         }
36 
37         // If there is an animation that has not yet started execution, it will be executed
38         if (!appearAnimator.isStarted()) {
39             appearAnimator.start();
40         }
41         break;
42 }

But there will still be conflicts. After detection, it is found that animation and vanishing animation interfere with each other. When the sliding has been suspended but the animation has not been completed, the sliding again triggers the vanishing animation.

Therefore, it is necessary to give an animation with a delay and cancel the animation if it is in a non-pause state. (Maybe the reason why the American Delivery Takeaway pause began to appear after a period of time is to prevent users from constantly sliding pause.)

The modified code is as follows:

case RecyclerView.SCROLL_STATE_DRAGGING:// Rolling
case RecyclerView.SCROLL_STATE_SETTLING:// Flying
    // Basic properties of vanishing animation (from iv Current x The coordinates go up to the right half of the screen.
    if (disappearAnimator == null) {
        disappearAnimator = ValueAnimator.ofFloat(originX, (float) (screenWidth - ivWidth / 2.0));
        disappearAnimator.setDuration(400);// Animation duration
        disappearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {// Value Update events
                float curValue = (float) animation.getAnimatedValue();
                iv.setX(curValue);
            }
        });
    }

    // If the animation has started at this time, cancel
    if (appearAnimator != null && appearAnimator.isStarted()) {
        appearAnimator.cancel();
    }

    // If the vanishing animation has not yet started to execute and iv If the location is in the original position, the execution will occur.
    if (!disappearAnimator.isStarted() && originX == iv.getX()) {
        disappearAnimator.start();
    }
    break;

The final effect is shown as follows:

summary

  • If we want to achieve other effects, such as fading in and fading out, the same can be achieved.
  • When multiple animations change the same View, we must pay attention to the conflict between animations.
  • Attribute animation + function equation can achieve some rich and changeable effects, which need to be studied.
  • The implementation of this article is still relatively simple, the best effect is that animation can be interrupted, because it is more troublesome, so it has not been achieved.

Github address: Initial battle of attribute animation

 

If you have any questions or suggestions, you can comment or mail The way to contact me, welcome your comments~

Keywords: Android Attribute github

Added by Fira on Fri, 09 Aug 2019 14:39:37 +0300