毋庸置疑,动画效果能提高用户体验。我们平时使用最多的动画基本上是属性动画和补间动画了,属性动画很强,基本能定制我们想要的动画,但是,API 21(5.0)后系统内置了Activity之间的切换动画,而且非常酷炫,非常有我们想要的感觉,今天我跟大家一起分享一下。我们知道,在两个Activity之间切换,我们一般会写出类似下面的代码:
Intent intent = new Intent(MainActivity.this, JupThreeActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.updown1,R.anim.updown2);
在API 21以后,我们可以使用内置的Activity切换动画啦。但是这样也就意味着只能兼容5.0之后的系统,我们先来看看一个效果图:
如果你对内置的 Shared Element还不够满意,你还可以定制View的过渡切换效果。步骤如下:
1.创建一个View的过渡移动的轨迹路径PathMotion类
我们可以创建ArcMotion对象,ArcMotion是PathMotion子类,是个曲线路径。想要了解更多ArcMotion可以查看【ArcMotion官方文档】
直接看看第二个Activity的代码吧:
public class SecondCustomTransActivity extends AppCompatActivity {
private ViewGroup container;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second_custom_trans);
container = (ViewGroup) findViewById(R.id.container);
getSupportActionBar().setTitle("这是第二个Activity");
//定义ArcMotion
ArcMotion arcMotion = new ArcMotion();
arcMotion.setMinimumHorizontalAngle(50f);
arcMotion.setMinimumVerticalAngle(50f);
//插值器,控制速度
Interpolator interpolator = AnimationUtils.loadInterpolator(this,android.R.interpolator.fast_out_slow_in);
//实例化自定义的ChangeBounds
CustomChangeBounds changeBounds = new CustomChangeBounds();
changeBounds.setPathMotion(arcMotion);
changeBounds.setInterpolator(interpolator);
changeBounds.addTarget(container);
//将切换动画应用到当前的Activity的进入和返回
getWindow().setSharedElementEnterTransition(changeBounds);
getWindow().setSharedElementReturnTransition(changeBounds);
}
public void dismiss(View v){
finishAfterTransition();
}
}
2.定义ChangeBounds类
我们自定义一个继承ChangeBounds的类,主要重写createAnimator函数,即创建你要执行的动画。这个函数由3个参数:
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;
// if (endValues.view instanceof ViewGroup) {
// ViewGroup vg = (ViewGroup) endValues.view;
// float offset = vg.getHeight() / 3;
// for (int i = 0; i < vg.getChildCount(); i++) {
// View v = vg.getChildAt(i);
// v.setTranslationY(offset);
// v.setAlpha(0f);
// v.animate()
// .alpha(1f)
// .translationY(0f)
// .setDuration(150)
// .setStartDelay(150)
// .setInterpolator(AnimationUtils.loadInterpolator(vg.getContext(),
// android.R.interpolator.fast_out_slow_in));
// offset *= 1.8f;
// }
// }
changeBounds.setDuration(300);
changeBounds.setInterpolator(AnimationUtils.loadInterpolator(sceneRoot.getContext(),
android.R.interpolator.fast_out_slow_in));
return changeBounds;
}
1).ViewGroup sceneRoot :
屏幕根View,即DecorView,第二个Activity的DecorView。
2).TransitionValues startValues : 属性动画的起始属性值,TransitionValues 对象内部有各Map类型的属性values,用于保存需要执行属性动画的属性。这个里面的属性值是在函数
captureStartValues
里放置,因此你可以重写
captureStartValues
函数,并把你自定义的属性动画中的属性放进去。
3).TransitionValues endValues :与startValues类似,表示属性动画结束时的属性值。可以通过重写
captureEndValues
函数,并把你自定义的属性动画里面的最终属性值放进去。
3.到这里就差不多了,下面我把Activity中的代码贴出来吧:
1).主函数代码(监听方法里):
Intent intent = new Intent(getActivity(), SecondCustomTransActivity.class);
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(getActivity(), view, "transition_morph_view");
startActivity(intent, options.toBundle());
ok,这个小Demo到这里就完成啦,遇到API的问题就直接 点击查看解决方法