Android动画<第六篇>:揭露动画

首先看一下效果图:

Android动画<第六篇>:揭露动画_第1张图片
30.gif

以上效果就是揭露动画了。

其布局如下:



    

        

            

            

        
    


    

    
        
    

其中,圆形按钮就是FloatingActionButton,上方的图片就是ImageView

Android SDK为揭露动画专门提供了一个工具类ViewAnimationUtils,其源码如下:

public final class ViewAnimationUtils {
    private ViewAnimationUtils() {}
    /**
     * Returns an Animator which can animate a clipping circle.
     * 

* Any shadow cast by the View will respect the circular clip from this animator. *

* Only a single non-rectangular clip can be applied on a View at any time. * Views clipped by a circular reveal animation take priority over * {@link View#setClipToOutline(boolean) View Outline clipping}. *

* Note that the animation returned here is a one-shot animation. It cannot * be re-used, and once started it cannot be paused or resumed. It is also * an asynchronous animation that automatically runs off of the UI thread. * As a result {@link Animator.AnimatorListener#onAnimationEnd(Animator)} * will occur after the animation has ended, but it may be delayed depending * on thread responsiveness. *

* Note that if any start delay is set on the reveal animator, the start radius * will not be applied to the reveal circle until the start delay has passed. * If it's desired to set a start radius on the reveal circle during the start * delay, one workaround could be adding an animator with the same start and * end radius. For example: *


     * public static Animator createRevealWithDelay(View view, int centerX, int centerY, float startRadius, float endRadius) {
     *     Animator delayAnimator = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, startRadius);
     *     delayAnimator.setDuration(delayTimeMS);
     *     Animator revealAnimator = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, endRadius);
     *     AnimatorSet set = new AnimatorSet();
     *     set.playSequentially(delayAnimator, revealAnimator);
     *     return set;
     * }
     * 
* * @param view The View will be clipped to the animating circle. * @param centerX The x coordinate of the center of the animating circle, relative to * view. * @param centerY The y coordinate of the center of the animating circle, relative to * view. * @param startRadius The starting radius of the animating circle. * @param endRadius The ending radius of the animating circle. */ public static Animator createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius) { return new RevealAnimator(view, centerX, centerY, startRadius, endRadius); } }

这个工具类中只有一个方法createCircularReveal

Animator createCircularReveal(View view, int centerX,  int centerY, float startRadius, float endRadius)

其参数的意义分别是:

  • view:动画的目标view
  • centerX:确定动画圆的圆点x轴位置
  • centerY:确定动画圆的圆点y轴位置
  • startRadius:动画开始圆半径
  • endRadius:动画结束圆半径

参数设定思路:

  • view,就是上面布局代码中的ImageView
  • centerX和centerY,将圆形按钮FloatingActionButton的中心点作为动画的圆点
  • startRadius,动画的开始半径,这个可以随意设置,当然,为了效果最佳,建议将它设置为矩形图片的对角线长度
  • endRadius,当动画结束时的半径,这个可以随意设置,当然,为了效果最佳,建议将它设置为圆形按钮的半径长度,货值直接设置为0

实现代码如下:

            Animation animation = image.getAnimation();
            if (animation != null) {
                animation.cancel();
            }

            int[] vLocation = new int[2];//存放按钮中心店的坐标,按钮的中心点作为揭露动画的圆点
            fab.getLocationInWindow(vLocation);
            int centerX = vLocation[0] + fab.getWidth() / 2;
            int centerY = vLocation[1] + fab.getHeight() / 2;

            CollapsingToolbarLayout collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar_layout);
            //求出对角线
            int hypotenuse = (int) Math.hypot(collapsingToolbarLayout.getWidth(), collapsingToolbarLayout.getHeight());

            if (isShow) {
                final Animator circularReveal = ViewAnimationUtils.createCircularReveal(image, centerX, centerY, hypotenuse, 0);
                circularReveal.setDuration(2000);
                circularReveal.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        image.setVisibility(View.GONE);
                        circularReveal.removeListener(this);
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {

                    }

                    @Override
                    public void onAnimationRepeat(Animator animation) {

                    }
                });
                circularReveal.start();
                isShow = false;
            } else {
                final Animator circularReveal = ViewAnimationUtils.createCircularReveal(image, centerX, centerY, 0, hypotenuse);
                circularReveal.setDuration(2000);
                circularReveal.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        circularReveal.removeListener(this);
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {

                    }

                    @Override
                    public void onAnimationRepeat(Animator animation) {

                    }
                });
                image.setVisibility(View.VISIBLE);
                circularReveal.start();
                isShow = true;
            }

[本章完...]

你可能感兴趣的:(Android动画<第六篇>:揭露动画)