Skip to content

实现 Activity 的切换动画

OCN Yang edited this page Mar 28, 2018 · 5 revisions

前引

这里的切换动画指的是 activity 跳转时的动画效果。这里总结了一下,有五种方式实现 activity 切换时实现动画效果。 下面我将依次介绍一下每种实现 activity 切换动画效果的实现方式。

在介绍 activity 的切换动画之前我们先来说明一下实现切换 activity 的两种方式:

  • 调用 startActivity 方法启动一个新的 Activity 并跳转其页面
  • 调用 finish 方法销毁当前的 Activity 返回上一个 Activity 界面

当调用 startActivity 方法的时候启动一个新的 Activity,这时候就涉及到了旧的 Activity 的退出动画和新的 Activity 的显示动画; 当调用 finish 方法的时候,销毁当前 Activity,就涉及到了当前 Activity 的退出动画和前一个 Activity 的显示动画;

所以我们的 Activity 跳转动画是分为两个部分的:一个 Activity 的销毁动画与一个 Activity 的显示动画。
明白了这一点之后我们开始看一下第一种实现 Activit y跳转动画的方式: 通过 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 方法
        Intent intent = new Intent(MainActivity.this, SecondActivity.class);
        startActivity(intent);
        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 方法的定义, 我们在 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.
 */
public void overridePendingTransition(int enterAnim, int exitAnim) {...}

通过这段注释我们能够知道:

  • overridePendingTransition 方法需要在 startActivity 方法或者是 finish 方法调用之后立即执行
  • 参数 enterAnim 表示的是从 Activity a 跳转到 Activity b,进入 b 时的动画效果
  • 参数 exitAnim 表示的是从 Activity a 跳转到 Activity b,离开 a 时的动过效果
  • 若进入 b 或者是离开 a 时不需要动画效果,则可以传值为 0

我们来看一下是不是这样的,首先看一下如果我们在 startActivity 方法调用之后不立即执行 overridePendingTransition 方法, 会有动画效果么?

若我们将 overridePendingTransition 延时 1s 执行呢?

/**
 * 点击按钮实现跳转逻辑
 */
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_out_left);
        // 延时1s执行overridePendingTransition方法 
        button1.postDelayed(new Runnable() {
            @Override
            public void run() {
                overridePendingTransition(R.anim.slide_in_top, R.anim.slide_in_top);
            }
        }, 1000);
    }
});

执行之后我们能够发现跳转动画没有了,所以 overridePendingTransition 只能在 startActivity 或者是 finish 方法之后执行。

还有一个问题,如果是在 startActivity 之后执行,只是在子线程中执行呢?Activity 的跳转动画能够执行么?

/**
 * 点击按钮实现跳转逻辑
 */
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_out_left);
        /**
         * 在子线程中执行overridePendingTransition方法
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_left);
            }
        }).start();

    }
});

测试后发现 Activity 的切换效果还是执行,也就是说 overridePendingTransition 方法也是可以在子线程中执行的, 当然这并没什么卵用。

好吧,在介绍完了使用 overridePendingTransition 方法实现 Activity 切换动画之后我们下面看一下使用 style 的方式定义实现 Activity 的切换动画。

二、使用 style 的方式定义 Activity 的切换动画

1_ 定义 Application 的 style

<!-- 系统Application定义 -->
<application
    Android:allowBackup="true"
    Android:icon="@mipmap/ic_launcher"
    Android:label="@string/app_name"
    Android:supportsRtl="true"
    Android:theme="@style/AppTheme">

2_ 定义具体的 AppTheme 样式

其中这里的 windowAnimationStyle 就是我们定义 Activity 切换动画的 style。而 @anim/slide_in_top 就是我们定义 的动画文件,也就是说通过为 Application 设置 style,然后为 windowAnimationStyle 设置动画文件就可以全局的为 Activity 的跳转配置动画效果。

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="Android:windowAnimationStyle">@style/activityAnim</item>
</style>

<!-- 使用style方式定义activity切换动画 -->
<style name="activityAnim">
    <item name="Android:activityOpenEnterAnimation">@anim/slide_in_top</item>
    <item name="Android:activityOpenExitAnimation">@anim/slide_in_top</item>
</style>

而在 windowAnimationStyle 中存在四种动画:

  • activityOpenEnterAnimation // 用于设置打开新的 Activity 并进入新的 Activity 展示的动画
  • activityOpenExitAnimation // 用于设置打开新的 Activity 并销毁之前的 Activity 展示的动画
  • activityCloseEnterAnimation // 用于设置关闭当前 Activity 进入上一个 Activity 展示的动画
  • activityCloseExitAnimation // 用于设置关闭当前 Activity 时展示的动画

3_ 测试代码,实现 Activity 切换操作

/**
 * 点击按钮,实现Activity的跳转操作
 * 通过定义style的方式实现activity的跳转动画
 */
button2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        /**
         * 普通的Intent跳转Activity实现
         */
        Intent intent = new Intent(MainActivity.this, SecondActivity.class);
        startActivity(intent);
    }
});

这时候我们我们执行 diamante 逻辑之后就能发现 Activity 在切换的时候出现了动画效果,说明我们设置的 style 起作用了。

三、使用 ActivityOptions 切换动画实现 Activity 跳转动画

四、使用 ActivityOptions 之后内置的动画效果通过 style 的方式

五、使用 ActivityOptions 动画共享组件的方式实现跳转 Activity 动画

以上三、四、五、皆属于 转场动画范畴,
请到 《Ⅵ. Transition Animation / 转场动画 & 共享元素》 查看详细讲解。

附录
摘录自:原文地址

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.