前言
在介绍activity的切换动画之前我们先来说明一下实现切换activity的两种方式:
1,调用startActivity方法启动一个新的Activity并跳转其页面
2,调用finish方法销毁当前的Activity返回上一个Activity界面
当调用startActivity方法的时候启动一个新的activity,这时候就涉及到了旧的Activity的退出动画和新的Activity的显示动画;
当调用finish方法的时候,销毁当前Acitivity,就涉及到了当前Activity的退出动画和前一个Activity的显示动画;
所以我们的activity跳转动画是分为两个部分的:一个Activity的销毁动画与一个Activity的显示动画,知道这些之后我们开始今天跳转动画的5种实现方式的讲解,其中后面介绍的三种方式都是Android 5.0以后的api支持的。
本文转载自 https://blog.csdn.net/qq_23547831/article/details/51821159
(一)使用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方法我们再强调以下几点:
1,overridePendingTransition方法需要在startAtivity方法或者是finish方法调用之后执行
2,参数enterAnim表示的是从Activity a跳转到Activity b,进入b时的动画效果
3,参数exitAnim表示的是从Activity a跳转到Activity b,离开a时的动过效果
4,若进入b或者是离开a时不需要动画效果,则可以传值为0
(二)使用style的方式定义Activity的切换动画
1,定义Application的theme,一般我们创建的应用默认都会配置一个theme主题的:
<!-- 系统Application定义 -->
<application
Android:allowBackup="true"
Android:icon="@mipmap/ic_launcher"
Android:label="@string/app_name"
Android:supportsRtl="true"
Android:theme="@style/AppTheme">
2,定义具体的AppTheme样式:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<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就是我们定义Activity切换动画的style。而@anim/slide_in_top就是我们定义的动画文件,也就是说通过为Appliation设置style,然后为windowAnimationStyle设置动画文件就可以全局的为Activity的跳转配置动画效果。
在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);
}
});
此时我们只需正常实现跳转逻辑,就会发现我们在style中设置的切换动画生效了。
(三)使用ActivityOptions切换动画实现Activity跳转动画
上面我们讲解的通过overridePendingTransition方法基本上可以满足我们日常中对Activity跳转动画的需求了,但是MD风格出来之后,overridePendingTransition这种老旧、生硬的方式怎么能适合我们的MD风格的App呢?好在google在新的sdk中给我们提供了另外一种Activity的过度动画——ActivityOptions。并且提供了兼容包——ActivityOptionsCompat。ActivityOptionsCompat是一个静态类,提供了相应的Activity跳转动画效果,通过其可以实现不少炫酷的动画效果。
1,在跳转的Activity中设置contentFeature,即在调用setContentView方法前添加下面几行代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置activity的窗口属性为contentFeature,即可使用切换动画
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
Transition explode = TransitionInflater.from(this).inflateTransition(Android.R.transition.explode);
// 此处获取了系统内置的explode动画效果设置给了activity的窗口对象
getWindow().setEnterTransition(explode);
setContentView(R.layout.activity_three);
}
2,在startActivity执行跳转逻辑的时候调用startActivity的重写方法,执行ActivityOptions.makeSceneTransitionAnimation方法:
/**
* 点击按钮,实现Activity的跳转操作
* 通过Android5.0及以上代码的方式实现activity的跳转动画
*/
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ThreeActivity.class);
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle());
}
});
这里我们调用了startActivity的重载方法:
public void startActivity(Intent intent, @Nullable Bundle options)
并且我们传入了ActivityOptions.makeSceneTransitionAnimation,该方法表示将Activity a平滑的切换到Activity b,其还有几个重载方法可以指定相关的View,即以View为焦点平滑的从Activity a切换到Activity b。
调用这段代码之后我们activity跳转的时候就展示出了动画效果:
(四)使用ActivityOptions之后内置的动画效果通过style的方式
1,编写过渡动画文件
首先我们需要在Application项目res目录下新建一个transition目录,然后创建资源文件,然后使用这些系统自带的过渡动画效果,这里设置了过度时长为300ms。
<explode xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:duration="300" />
2,
<!-- 系统Application定义 -->
<application
Android:allowBackup="true"
Android:icon="@mipmap/ic_launcher"
Android:label="@string/app_name"
Android:supportsRtl="true"
Android:theme="@style/AppTheme">
在Application的theme对应的AppTheme的style样式中指定过渡动画效果为我们刚刚定义的过渡动画文件:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="Android:windowEnterTransition">@transition/activity_explode</item>
<item name="Android:windowExitTransition">@transition/activity_explode</item>
</style>
3,执行跳转逻辑:
/**
* 点击按钮,实现Activity的跳转操作
* 通过Android5.0及以上style的方式实现activity的跳转动画
*/
button4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
* 调用ActivityOptions.makeSceneTransitionAnimation实现过度动画
*/
Intent intent = new Intent(MainActivity.this, FourActivity.class);
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle());
}
});
这样执行之后也可以展示出Activity跳转过度动画了,其和通过代码方式实现的效果是类似的,只是少了在setContentView方法调用前的几句代码的添加,而且这种动画效果是全局的。
(五)使用ActivityOptions动画共享组件的方式实现跳转Activity动画
这里的共享组件动画效果是指在前面一个Activity的某个子View与后面一个Activity的某个子View之间建立过渡效果,然后在这种过度效果下同时实现Activity的跳转操作。那么如何实现两个组件View之间实现过渡效果呢?
1,定义共享关联组件1
为Activity a中的button按钮设置transitionName属性,记住该属性值后面会用到:
<Button
Android:id="@+id/button5"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_below="@+id/button4"
Android:layout_marginTop="10dp"
Android:layout_marginRight="10dp"
Android:layout_marginLeft="10dp"
Android:text="组件过度动画"
Android:background="@color/colorPrimary"
Android:transitionName="shareNames"
/>
2,定义共享关联组件2
同样的在Activity b的布局文件中为需要和Activity a中button建立关联的组件也定义transitionName属性,并且这两个组件的transitionName属性的值必须是相同的,这样这两个组件相当于有了过度对应关系,如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/activity_second"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:gravity="center_horizontal"
Android:orientation="vertical"
Android:transitionName="shareNames"
>
<TextView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@color/colorAccent"
Android:layout_marginTop="10dp"
Android:layout_marginBottom="10dp"
/>
</LinearLayout>
3,调用startActivity执行跳转动画
/**
* 点击按钮,实现Activity的跳转操作
* 通过Android5.0及以上共享组件的方式实现activity的跳转动画
*/
button5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, FiveActivity.class);
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, button5, "shareNames").toBundle());
}
});
需要说明的是这里调用的ActivityOptions.makeSceneTransitionAnimation方法,传递了三个参数,其中第一个参数为context对象,第二个参数为启动Activity的共享组件,第三个参数为启动Activity的共享组件transitionName属性值。
这样经过调用之后我们就实现了从Activity a跳转到Activity b的时候a中的组件到b中组件的过度效果: