文章目录
相信大部分的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的逻辑,具体代码如下:
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
* 在调用了startActivity方法之后立即调用overridePendingTransition方法
* 第一个参数:新Activity的进入动画
* 第二个参数:当前Activity的退出动画
*/
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
// 设置过渡动画:这里两个参数都用了slide_in_left,实际使用时通常会分别设置进入和退出动画
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_in_left);
}
});
可以看到我们在调用了startActivity方法之后又执行了overridePendingTransition方法,而在overridePendingTransition方法中传递了两个动画布局文件,我们首先看一下这里的动画文件具体是怎么实现的:
<?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方法在定义的时候有这样的一段注释说明:
/**
* Call immediately after one of the flavors of {@link #startActivity(Intent)}
* or {@link #finish} to specify an explicit transition animation to
* perform next.
*/
/**
* @param enterAnim A resource ID of the animation resource to use for
* the incoming activity. Use 0 for no animation.
* @param exitAnim A resource ID of the animation resource to use for
* the outgoing activity. Use 0 for no animation.
*/
- 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属性:
<?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执行跳转动画
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中组件的过度效果。