十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
所谓转场动画,通俗的讲就是一个Activity跳转到另一个Activity是的动画;Activity的转场动画很早就有了,5.0之前用的是overridePendingTransition()这个方法。在5.0之后,Google使用Material Design设计风格,进而有了的新的转场转场动画的诞生,效果还是挺炫酷的;今天我们就来讲解下。

1、API21之前Activity过渡动画使用
API21之前Activity过渡动画通过两种方式来实现:style主题里面统一设置、使用代码overridePendingTransition函数单独设置;
style文件主题里面统一定义,全局为所有Activity设置过渡动画效果;
- @style/Animation.Activity.Customer
 - @anim/right_in
 - @anim/left_out
 - @anim/left_in
 - @anim/right_out
 
代码overridePendingTransition(enterAnim, exitAnim);
关于overridePendingTransition函数,有一个需要注意的地方就是:它必需紧挨着startActivity()或者finish()或者onBackPressed()函数调用,否则不一定有效果;
2、API 21 之后Activity过渡动画使用
在API 21之后google又推出了一种比之前效果更加赞的过渡动画;
通过ActivityOptions + Transition来实现Activity过渡动画;
所以在使用之前需要进行版本判断。当版本API 大于21时使用转场动画,否则不使用;
- // Check if we're running on Android 5.0 or higher
 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
 - // Apply activity transition
 - } else {
 - // Swap without transition
 - }
 
ActivityOptions + Transition来实现Activity过渡动画之前先来了看下ActivityOptions里面几个函数代表啥意思;
- /**
 - * 和overridePendingTransition类似,设置跳转时候的进入动画和退出动画
 - */
 - public static ActivityOptions makeCustomAnimation(Context context, int enterResId, int exitResId);
 - /**
 - * 通过把要进入的Activity通过放大的效果过渡进去
 - * 举一个简单的例子来理解source=view,startX=view.getWidth(),startY=view.getHeight(),startWidth=0,startHeight=0
 - * 表明新的Activity从view的中心从无到有慢慢放大的过程
 - */
 - public static ActivityOptions makeScaleUpAnimation(View source, int startX, int startY, int width, int height);
 - /**
 - * 通过放大一个图片过渡到新的Activity
 - */
 - public static ActivityOptions makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY);
 - /**
 - * 场景动画,体现在两个Activity中的某些view协同去完成过渡动画效果,等下在例子中能更好的看到效果
 - */
 - public static ActivityOptions makeSceneTransitionAnimation(Activity activity, View sharedElement, String sharedElementName);
 - /**
 - * 场景动画,同上是对多个View同时起作用
 - */
 - public static ActivityOptions makeSceneTransitionAnimation(Activity activity, android.util.Pair
 ... sharedElements); 
对于Transition Activity过渡动画的使用,我们简单的分为三个步骤:告诉系统以Transition的方式启动Activity、定义过渡动画、设置过渡动画。
3、转场动画的使用场景
Android中的转场动画主要有三种场景:
下面分别详细的介绍。
1、两个activity之间切换时界面的过渡效果
两个activity切换时的,有两个动画,从activity A 切换到activity B时,会有A的退出动画和B的进入动画;
在Google提供的android.transition.Transition包中从activity A切换到activity B有三种方式:Explode, Slide 和Fade;
上面的三种动画有两种实现方式:
①通过xml声明;
在res目录下新建transition文件夹在transition文件夹下新建activity_fade.xml文件;
activity_fade.xml
- android:duration="1000"/>
 
activity_slide.xml
- android:duration="1000"/>
 
ActivityA的代码如下:因为从ActivityA切换到ActivityB,所以ActivityA是退出动画使用的方法是:getWindow().setExitTransition(slide);
- @Override
 - protected void onCreate(Bundle savedInstanceState) {
 - super.onCreate(savedInstanceState);
 - setContentView(R.layout.activity_transition);
 - setupWindowAnimations();
 - }
 - private void setupWindowAnimations() {
 - Slide slide = TransitionInflater.from(this).inflateTransition(R.transition.activity_slide);
 - getWindow().setExitTransition(slide);
 - }
 
ActivityB是进入动画使用方法:getWindow().setEnterTransition(fade);,ActivityB的代码如下
- @Override
 - protected void onCreate(Bundle savedInstanceState) {
 - super.onCreate(savedInstanceState);
 - setContentView(R.layout.activity_transition);
 - setupWindowAnimations();
 - }
 - private void setupWindowAnimations() {
 - Fade fade = TransitionInflater.from(this).inflateTransition(R.transition.activity_fade);
 - getWindow().setEnterTransition(fade);
 - }
 
②代码方式
ActivityA代码如下:实现一个Slide对象并且设置时间为1000毫秒
- @Override
 - protected void onCreate(Bundle savedInstanceState) {
 - super.onCreate(savedInstanceState);
 - setContentView(R.layout.activity_transition);
 - setupWindowAnimations();
 - }
 - private void setupWindowAnimations() {
 - Slide slide = new Slide();
 - slide.setDuration(1000);
 - getWindow().setExitTransition(slide);
 - }
 
ActivityB中实现一个Fide对象并且设置时间为1000毫秒;
- @Override
 - protected void onCreate(Bundle savedInstanceState) {
 - super.onCreate(savedInstanceState);
 - setContentView(R.layout.activity_transition);
 - setupWindowAnimations();
 - }
 - private void setupWindowAnimations() {
 - Fade fade = new Fade();
 - fade.setDuration(1000);
 - getWindow().setEnterTransition(fade);
 - }
 
Shared elements转换确定两个Activity之间共享的视图如何在这两个Activity之间转换;
如果两个Activity在不同的位置和大小中具有相同的图像,则通过Shared elements转换会在这两个Activity之间平滑地转换和缩放图像;
当从Activity A跳转到Activity B时,ActivityA, ActivityB中的两个item有动画变化,但是要注意的时ActivityA ,ActivityB中的item是两个独立的item;
shared elements转换包括以下几种:
实现上面的效果需要三个步骤:
① Window Content Transition
设置styles.xml文件,允许windowContentTransitions如下:
- value/style.xml
 - ...
 - true
 - ...
 
②定义一个相同的transition名称
分别在Activity A 和Activity B的布局文件中定义item,这两个item的属性可以不一样,但是android:transitionName必须一样。如下:
- android:id="@+id/small_blue_icon"
 - style="@style/MaterialAnimations.Icon.Small"
 - android:src="@drawable/circle"
 - android:transitionName="@string/blue_name" />
 
activity_b.xml
- android:id="@+id/big_blue_icon"
 - style="@style/MaterialAnimations.Icon.Big"
 - android:src="@drawable/circle"
 - android:transitionName="@string/blue_name" />
 
③在activity中启动shared element
使用ActivityOptions.makeSceneTransitionAnimation()方法
ActivityA.java
- blueIconImageView.setOnClickListener(new View.OnClickListener() {
 - @Override
 - public void onClick(View v) {
 - Intent i = new Intent(MainActivity.this, SharedElementActivity.class);
 - View sharedView = blueIconImageView;
 - String transitionName = getString(R.string.blue_name);
 - ActivityOptions transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, sharedView, transitionName);
 - startActivity(i, transitionActivityOptions.toBundle());
 - }
 - });
 
Fragment之间Shared elements
Fragment之间的Shared elements的使用过程和Activity之间的类似,分为三个步骤:
①允许windowContentTransitions
- ...
 - true
 - ...
 
②定义一个共同的变换名称
layout/fragment_a.xml
- android:id="@+id/small_blue_icon"
 - style="@style/MaterialAnimations.Icon.Small"
 - android:src="@drawable/circle"
 - android:transitionName="@string/blue_name" />
 
layout/fragment_b.xml
- android:id="@+id/big_blue_icon"
 - style="@style/MaterialAnimations.Icon.Big"
 - android:src="@drawable/circle"
 - android:transitionName="@string/blue_name" />
 
③使用FragmentTransaction
- FragmentB fragmentB = FragmentB.newInstance(sample);
 - // Defines enter transition for all fragment views
 - Slide slideTransition = new Slide(Gravity.RIGHT);
 - slideTransition.setDuration(1000);
 - sharedElementFragment2.setEnterTransition(slideTransition);
 - // Defines enter transition only for shared element
 - ChangeBounds changeBoundsTransition = TransitionInflater.from(this).inflateTransition(R.transition.change_bounds);
 - fragmentB.setSharedElementEnterTransition(changeBoundsTransition);
 - getFragmentManager().beginTransaction()
 - .replace(R.id.content, fragmentB)
 - .addSharedElement(blueView, getString(R.string.blue_name))
 - .commit();