相信大部分的Android开发者都已经知道Activity的跳转方式(eg:通过intent跳转),也见过市面上app页面互相跳转的炫酷动效。今天我们就来详细了解一下Activity之间跳转的动画是咋制作的?
前言 在介绍activity的切换动画之前我们先来说明一下实现切换activity的两种方式:
调用startActivity方法启动一个新的Activity并跳转其页面
当调用startActivity方法的时候启动一个新的activity,这时候就涉及到了旧的Activity的退出动画和新的Activity的显示动画;
调用finish方法销毁当前的Activity返回上一个Activity界面
当调用finish方法的时候,销毁当前Acitivity,就涉及到了当前Activity的退出动画和前一个Activity的显示动画;
所以我们的activity跳转动画是分为两个部分的:一个Activity的销毁动画与一个Activity的显示动画 ,明白了这一点之后我们开始看一下第一种实现Activity跳转动画的方式:通过overridePendingTransition方法实现Activity切换动画。
一、使用overridePendingTransition方法实现Activity跳转动画 overridePendingTransition方法是Activity中提供的Activity跳转动画方法,通过该方法可以实现Activity跳转时的动画效果。下面我们就将通过一个简单的例子看一下如何通过overridePendingTransition方法实现Activity的切换动画。 demo例子中我们实现了Activity a中有一个点击按钮,点击按钮实现跳转Activity b的逻辑,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this , SecondActivity.class ); startActivity(intent); overridePendingTransition(R.anim.slide_in_left, R.anim.slide_in_left); } });
可以看到我们在调用了startActivity方法之后又执行了overridePendingTransition方法,而在overridePendingTransition方法中传递了两个动画布局文件,我们首先看一下这里的动画文件具体是怎么实现的:
1 2 3 4 5 6 7 8 9 <?xml version="1.0" encoding="utf-8" ?> <set xmlns:Android ="http://schemas.Android.com/apk/res/Android" Android:shareInterpolator ="false" Android:zAdjustment ="top" > <translate Android:duration ="200" Android:fromXDelta ="-100.0%p" Android:toXDelta ="0.0" /> </set >
这里的overridePendingTransition方法传递的是两个动画文件id,第一个参数是需要打开的Activity进入时的动画,第二个参数是需要关闭的Activity离开时的动画。这样我们执行了这段代码之后在跳转Activity的时候就展示了动画效果: 动画的效果是通过overridePendingTransition方法实现的,那么下面我们来看一下overridePendingTransition方法的定义,我们在overridependingTransition方法在定义的时候有这样的一段注释说明:
overridePendingTransition方法需要在startAtivity方法或者是finish方法调用之后立即执行
参数enterAnim表示的是从Activity a跳转到Activity b,进入b时的动画效果
参数exitAnim表示的是从Activity a跳转到Activity b,离开a时的动过效果
若进入b或者是离开a时不需要动画效果,则可以传值为0
二、使用ActivityOptions动画共享组件的方式实现跳转Activity动画 在有些场景中,Activity之间会共用一些view以便页面跳转时能过更加丝滑。这就不得不用到ActivityOptions来实现了。 这里的共享组件动画效果是指将前面一个Activity的某个子View与后面一个Activity的某个子View之间有过渡效果,即在这种过度效果下实现Activity的跳转操作。那么如何实现两个组件View之间实现过渡效果呢?
2.1定义共享组件 为Activity b中的ImageView设置transitionName属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <?xml version="1.0" encoding="utf-8" ?> <LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:tools ="http://schemas.android.com/tools" android:layout_width ="match_parent" android:layout_height ="match_parent" android:orientation ="vertical" tools:context =".页面跳转动画.ActivityB" > <ImageView android:id ="@+id/imageView" android:layout_width ="match_parent" android:layout_height ="300dp" android:src ="@drawable/ic_launcher_foreground" android:transitionName ="sharedElement" /> <TextView android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_marginTop ="10dp" android:gravity ="center" android:text ="我是页面B" android:textSize ="16sp" android:textStyle ="bold" /> <Button android:id ="@+id/jumpToAnotherActivity" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_marginTop ="10dp" android:gravity ="center" android:text ="回退到页面A" android:textSize ="14sp" /> <TextView android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_marginTop ="10dp" android:lineSpacingExtra ="6dp" android:padding ="16dp" android:text ="这是一段文字介绍:共享元素动画的本质是:让两个 Activity 中标记为 “同名共享元素” 的 View,在跳转时执行连贯的过渡动画,看起来像是同一个元素从第一个页面 “移动” 到第二个页面。\n要使动画生效,必须满足以下条件: 1. ActivityA 中:共享的 View(如imageView)无需额外配置,但需在代码中通过makeSceneTransitionAnimation指定。 2. ActivityB 中:对应的共享 View 必须在布局文件中设置android:transitionName属性,且值与代码中的“完全一致”" android:textSize ="14sp" /> </LinearLayout >
在Activity b的布局文件中为组件定义transitionName 属性,这样这两个组件相当于有了过渡(transition)对应关系,这里需要注意的是这两个组件的transitionName属性的值必须是相同的。
2.2 调用startActivity执行跳转动画 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class ActivityA : AppCompatActivity () { private lateinit var btn: Button private lateinit var imageView: ImageView override fun onCreate (savedInstanceState: Bundle ?) { super .onCreate(savedInstanceState) setContentView(R.layout.activity_a) btn = findViewById(R.id.jumpToAnotherActivity) imageView = findViewById(R.id.imageView) btn.setOnClickListener { startActivity( Intent(this ,ActivityB::class .java), ActivityOptionsCompat.makeSceneTransitionAnimation(this ,imageView,"sharedElement" ).toBundle() ) } } }
需要说明的是这里调用的ActivityOptions.makeSceneTransitionAnimation 方法,传递了三个参数,其中第一个参数为context对象,第二个参数为启动Activity的共享组件,第三个参数为启动Activity的共享组件transitionName属性值。 这样经过调用之后我们就实现了从Activity a跳转到Activity b的时候a中的组件到b中组件的过度效果。