扩散动画跳转,就是去掉原有的切换动画,换成自己的动画效果,比如,现在默认的滑动切换,每次跳转activity都是原布局滑出,新布局同时滑入,或者是原有布局不变,新布局直接滑入等等。
这个是通过取消掉原油动画,换成自己定义的动画,原理很简单,就是通过获取你点击位置的屏幕坐标,将坐标传递到下一个界面,然后进行动画。
下面是代码:
首先是动画工具类:
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 ; int[] center = {x,y}; return center; } //设置开始动画 public static void setActivityStartAnim(final Activity activity, final View view, final Intent intent){ 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) {//对控件View进行判空,防止后台时间过长activity被回收后启动 Animator animator = createRevealAnimator(activity, view, false, mX, mY); animator.start(); } } } }); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private static Animator createRevealAnimator(final Activity activity, final View view, boolean reversed, int x, int y) { 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 = ViewAnimationUtils.createCircularReveal( view, x, y, startRadius, endRadius); animator.setDuration(800); animator.setInterpolator(new AccelerateDecelerateInterpolator()); if (reversed) { 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; } }
这是最主要的,然后就是布局,很简单,写两个Activity,布局随意,然后写一个跳转逻辑就可以了,在跳转中进行调用,注意的是,如果你想从哪里跳转,比如,点击按钮跳转,动画从点击处开始,那么久传入点击的控件,下面是调用:
b2 = findViewById(R.id.b2); b2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //获得屏幕坐标 int[] viewCenter = ViewCenterUtils.getViewCenter(b2); Intent intent = new Intent(MainActivity.this, MyActivity.class); intent.putExtra("x", viewCenter[0]); intent.putExtra("y", viewCenter[1]); startActivity(intent); } });
很简单吧,就是一个找到控件ID,设置点击事件,获得坐标点,然后跳转传值,接下来就是在跳转类中做动画了。
LinearLayout ll=findViewById(R.id.ll); ViewCenterUtils.setActivityStartAnim(this, ll, getIntent());
接受类中只需要这两行代码就可以了,注意的是,控件是最大的布局ID,下面就是工具类调用,传入上下文,控件,然后就是intent传递的坐标点,用来作为起始动画。
如果你往工具类中传入的不是父控件,而是随意的一个控件,比如Textview什么的,那么,动画就只会作用在这个Textview上,儿整体是没有动画的!
到了这里,动画基本上就完成了,但是你会发现,依然会进行正常的切换跳转,然后在界面展示出来之后,才会进行动画,是不是?
嗯,因为我们还少了一个步骤,需要关闭原有的切换动画才行,这样没有了原有的动画,只有我们的,不就会执行我们的了吗!
首先,在res/values/styles中写点东西
加上这个
<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>然后在清单文件中进行调用
<activity android:name=".MainActivity" android:theme="@style/noAnimTheme" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MyActivity" android:theme="@style/noAnimTheme"/> <activity android:name=".TheredActivity" />完成了,这样跳转动画就有了!注意的是,需要自己再设置一个背景,不然的话,自己试试吧,影响并不大(大概?)。