1:从点击的位置向外扩散 揭露
2:收回到点击的位置
3:如果点击的位置是可变动的(例如悬浮球) view 会收回到悬浮球最后所在位置
从而达到更好的用户体验和视觉效果
//首先准备一个获取点击view在屏幕中的中心点坐标和 扩散动画的工具类 话不多说 直接上代码
import android.animation.Animator;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.animation.AccelerateDecelerateInterpolator;
public class ViewCenterUtils {
private static int mX;
private static int mY;
//得到视图中心
public static int[] getViewCenter(View view) {
int top = view.getTop();
int left = view.getLeft();
int bottom = view.getBottom();
int right = view.getRight();
int x1 = (right - left) / 2;
int y1 = (bottom - top) / 2;
int[] location = new int[2];
view.getLocationOnScreen(location);
int x2 = location[0];
int y2 = location[1];
int x = x2 + x1;
int y = y2+y1;
int[] center = {x, y};
return center;
}
//设置开始动画 第一个参数 执行动画的view 第二个参数 点击的view 第三个参数intent 携带参数 后面会提到 第四个参数是展开动画还是关闭动画
public static void setActivityAnim(final Activity activity, final View view, final Intent intent,boolean isShow) {
view.post(new Runnable() {
@Override
public void run() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mX = intent.getIntExtra("x", 0);
mY = intent.getIntExtra("y", 0);
if (view != null) {
Animator animator = createRevealAnimator(activity, view, false, mX, mY,isShow);
animator.start();
}
}
}
});
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private static Animator createRevealAnimator(final Activity activity, final View view, boolean reversed, int x, int y,boolean isStart) {
int a = x;
int b = y;
int measuredHeight = view.getMeasuredHeight();
int screenWidth = activity.getWindowManager().getDefaultDisplay().getWidth();
int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
if (screenWidth - x > x) {
a = screenWidth - x;
}
if (screenHeight - y > y) {
b = screenHeight - y;
}
// float hypot = (float) Math.hypot(screenWidth, screenHeight-measuredHeight);
// float hypot = (float) Math.hypot(x, y);
float hypot = (float) Math.hypot(a, b);
float startRadius = reversed ? hypot : 0;
float endRadius = reversed ? 0 : hypot;
Animator animator;
if (isStart) {
animator = ViewAnimationUtils.createCircularReveal(view, x, y, startRadius, endRadius);
}else{
animator = ViewAnimationUtils.createCircularReveal(view, x, y, endRadius, startRadius);
}
animator.setDuration(800);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
if (!isStart) {
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
view.setVisibility(View.INVISIBLE);
activity.finish();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
return animator;
}
}
准备好工具类 再去看一下调用的地方
//点击事件 将view的中心坐标传递下去 执行动画时使用
int[] floatViewPosition = ViewCenterUtils.getViewCenter(view);
Intent intent = new Intent(context, ControlActivity.class);
intent.putExtra("x", floatViewPosition[0]);
intent.putExtra("y", floatViewPosition[1]);
context.startActivity(intent);
//在ControlActivity 设置完布局后 调用 view一定是根布局最大的view
ViewCenterUtils.setActivityAnim(this, llView, getIntent(), true);
//onBackPressed() 方法中调用 不要主动调用finish 否则动画会无效 我们在动画执行完成后执行finish
ViewCenterUtils.setActivityStartAnim(this, llView, intent, false);
这样写完 动画就出来了 但是运行起来的效果不是你想要的 因为系统有原有的动画 我们写个属性去关闭原有切换view 动画 并在配置文件中给activity 设置属性
<style name="noAnimTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:duration">800</item>
</style>
还需要自己加个背景 不然你会有透视眼 写到这你就得到了一个非常好的效果了 自己去体会吧 拜拜
如果不明白的,可以看看这篇文章:
https://www.jianshu.com/p/57a7a5421b06