从动态图中看到,第一个Activity的小绿色方块到第二个Activity大绿色方块有个过渡效果~
接下来我们看看如何实现这个效果:
1.将两个Activity中需要过渡的View加上android:transitionName
属性
两个View的android:transitionName
属性取值要一致,比如:
第一个Activity布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/firstSharedView"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#00cc00"
android:onClick="onClick"
android:transitionName="sharedView" />
</RelativeLayout>
第二个Activity布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_alignParentBottom="true"
android:background="#00cc00"
android:onClick="onClick"
android:transitionName="sharedView" />
</RelativeLayout>
两个绿色的View都添加android:transitionName
属性,并且取名一致。
2.调用startActivity
ActivityOptions
的makeSceneTransitionAnimation
函数第一个参数Activity
没啥解释的,第二个参数就是第一个Activity
中的View
对象,第三个参数就是两个Activity
的View
的 android:transitionName
属性的值。
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, firstSharedView, "sharedView").toBundle());
现在就可以实现这种Shared Element
效果啦,但是可能你会想实现同时让两个View
有这样的效果,可是makeSceneTransitionAnimation
函数却只能让我们设置一个View
和一个transitionName
属性。如何添加多个呢?接下来我们一起学习让多个View同时有切换效果。
除了需要将两个Activity中需要过渡的View对应取相同的名称外,还需将需要过渡的View和transitionName
取值对应的String这两个对象封装到一个Pair对象中:
Pair first = new Pair<>(firstSharedView, ViewCompat.getTransitionName(firstSharedView));
Pair second = new Pair<>(secondSharedView, ViewCompat.getTransitionName(secondSharedView));
然后调用ActivityOptionsCompat类的makeSceneTransitionAnimation
的另一个重载函数makeSceneTransitionAnimation(Activity activity,
,第一个参数不解释,后面参数为不定长度的形参,即你可以传递任意多个Pair对象。
Pair<View, String>... sharedElements)
ActivityOptionsCompat transitionActivityOptions =
ActivityOptionsCompat.makeSceneTransitionAnimation(this, first, second);
最后调用startActivity
ActivityCompat.startActivity(this,
intent, transitionActivityOptions.toBundle());
说了这么多步骤,我们来看看效果吧~
自定义 Shared Element切换动画
如果你对内置的 Shared Element还不够满意,你还可以定制View的过渡切换效果。步骤如下:
1.创建一个View的过渡移动的轨迹路径PathMotion类
我们可以创建ArcMotion对象,ArcMotion是PathMotion子类,是个曲线路径。想要了解更多ArcMotion可以查看【ArcMotion官方文档】
ArcMotion arcMotion = new ArcMotion();
arcMotion.setMinimumHorizontalAngle(50f);
arcMotion.setMinimumVerticalAngle(50f);
2.定义ChangeBounds类
我们自定义一个继承ChangeBounds的类,主要重写createAnimator函数,即创建你要执行的动画。这个函数由3个参数:
1.
ViewGroup sceneRoot
:屏幕根View,即DecorView,第二个Activity的DecorView。
2.TransitionValues startValues
:属性动画的起始属性值,TransitionValues 对象内部有各Map类型的属性values,用于保存需要执行属性动画的属性。这个里面的属性值是在函数captureStartValues
里放置,因此你可以重写captureStartValues
函数,并把你自定义的属性动画中的属性放进去。
3.TransitionValues endValues
:与startValues类似,表示属性动画结束时的属性值。可以通过重写captureEndValues
函数,并把你自定义的属性动画里面的最终属性值放进去。
我们先看一个最简单的示例:
package com.hc.util;
import android.animation.Animator;
import android.transition.ChangeBounds;
import android.transition.TransitionValues;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
public class CustomChangeBounds extends ChangeBounds {
@Override
public Animator createAnimator(final ViewGroup sceneRoot,
TransitionValues startValues,
final TransitionValues endValues) {
Animator changeBounds = super.createAnimator(sceneRoot, startValues, endValues);
if (startValues == null || endValues == null || changeBounds == null)
return null;
changeBounds.setDuration(300);
changeBounds.setInterpolator(AnimationUtils.loadInterpolator(sceneRoot.getContext(),
android.R.interpolator.fast_out_slow_in));
return changeBounds;
}
}
看看效果吧~