在 Android 5.0 及更高的版本中,加入了一种全新的视觉动画效果,就是揭露动画。揭露动画在系统中很常见,就是类似波纹的效果, 从某一个点向四周展开或者从四周向某一点聚合起来,本文实现的效果如下所示,可以用在 Activity 里面的 View 动画效果, 也可以使用在 Activity 跳转过渡动画中,如下图使用在 View 的显示隐藏的效果图:
使用揭露动画非常简单,Android Sdk 中已经帮我们提供了一个工具类 ViewAnimationUtils 来创建揭露动画。ViewAnimationUtils
里面只有一个静态方法 createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius)
,
返回一个 Animator 动画对象。
public final class ViewAnimationUtils {
private ViewAnimationUtils() {}
/**
* ......
* @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
* <code>view</code>.
* @param centerY The y coordinate of the center of the animating circle, relative to
* <code>view</code>.
* @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);
}
}
ViewAnimationUtils.createCircularReveal()
方法能够为裁剪区域添加动画以揭露或隐藏视图。我们主要使用 createCircularReveal 方法,
该方法有四个参数:
如下图所示:
揭露动画有两种效果,一种是显示一组UI元素,另一种是隐藏一组UI元素:
注意:揭露动画对象只能使用一次,不能被重新使用,也就是说每次使用揭露动画都要调用 ViewAnimationUtils.createCircularReveal() 返回一个揭露动画对象使用,同时一旦开始了动画就不能暂停或重新开始。揭露动画是一种异步动画,可以自动运行在 UI 线程上。 当揭露动画结束后,如果设置了 Animator.AnimatorListener 监听器,那么监听器的 onAnimationEnd(Animator) 方法会被调用, 但可能会被延迟调用,这取决于线程的响应能力。
Reveal Animation 要掌握的内容就这么多了,这里通过粗略分析一个实例来介绍一下具体用法,(详细代码请查看 Demo)。
这里以上面的效果图来分析:
通过这个分析图,其实应该就很容易理解了,我们要做的所有事情就是确定 ViewAnimationUtils.createCircularReveal()
这
个方法的四个参数。
这里查看具体的代码:
fab.setOnClickListener(... {
launchRevealAnimation();
});
private void launchRevealAnimation() {
//求出第2个和第3个参数
int[] vLocation = new int[2];
fab.getLocationInWindow(vLocation);
int centerX = vLocation[0] + fab.getWidth() / 2;
int centerY = vLocation[1] + fab.getHeight() / 2;
//求出要揭露 View 的对角线,来作为扩散圆的最大半径
int hypotenuse = (int) Math.hypot(mPuppet.getWidth(), mPuppet.getHeight());
if (flag) {//隐藏 揭露对象
Animator circularReveal = ViewAnimationUtils.createCircularReveal(mPuppet, centerX, centerY, hypotenuse, 0);
circularReveal.setDuration(2000);
circularReveal.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {}
@Override
public void onAnimationEnd(Animator animation) {
mPuppet.setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animation) {}
@Override
public void onAnimationRepeat(Animator animation) {}
});
circularReveal.start();
flag = false;
} else {//显示 揭露对象
Animator circularReveal = ViewAnimationUtils.createCircularReveal(mPuppet, centerX, centerY, 0, hypotenuse);
circularReveal.setDuration(2000);
//注意:这里显示 mPuppet 调用并没有在监听方法里,并且是在动画开始前调用。
mPuppet.setVisibility(View.VISIBLE);
circularReveal.start();
flag = true;
}
}
上面就是实现一个揭露对象显示与隐藏的具体代码。没有任何难点,唯一要注意的是:显示揭露对象时并不是在动画监听方法的 onAnimationEnd
里
进行的。为什么要这样呢(我也是栽过这个坑里好久,后来才理解)?
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。