上一篇文章中我们讲解了在 Activity 启动过程中获取组件宽高的五种方式。在 Activity 的启动过程中如果我们直接在生命周期方法中通过 view.getWidth() 或者是 view.getHeight() 方法获取组件的宽度和高度其结果都是 0,为什么会出现这个问题呢?
其实看过我以前写过的 Activity 启动流程 Activity 布局加载流程 Activity 布局绘制流程的同学应该对 Activity 的启动流程和其布局加载绘制流程不陌生,Activity 的启动流程和 Activity 的布局文件加载绘制流程,其实没有相关的关系的,其实两个异步的加载流程,这样我们在 Activity 的 onCreate 或者是 onResume 方法中调用 textView.getHeight() 或者是 textView.getWidth() 方法的时候,Activity 对应的组件并没有执行完绘制流程,因此此时获取到的组件的宽高都是默认的 0,所以这时候通过 getWidth() 和 getHeight() 方法也就是无法获取组件的宽和高了。
文本中我们将讲解 activity 切换动画相关的知识点,这里的切换动画指的是是 activity 跳转时的动画效果。这里总结了一下,有五种方式实现 activity 切换时实现动画效果。下面我将依次介绍一下每种实现 activity 切换动画效果的实现方式。
在介绍 activity 的切换动画之前我们先来说明一下实现切换 activity 的两种方式:
当调用 startActivity 方法的时候启动一个新的 activity,这时候就涉及到了旧的 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方法 */
- Intent intent = new Intent(MainActivity.this, SecondActivity.class);
- startActivity(intent);
- overridePendingTransition(R.anim.slide_in_left, R.anim.slide_in_left);
- }
- });
可以看到我们在调用了 startActivity 方法之后又执行了 overridePendingTransition 方法,而在 overridePendingTransition 方法中传递了两个动画布局文件,我们首先看一下这里的动画文件具体是怎么实现的:
这里的 overridePendingTransition 方法传递的是两个动画文件 id,第一个参数是需要打开的 Activity 进入时的动画,第二个参数是需要关闭的 Activity 离开时的动画。这样我们执行了这段代码之后在跳转 Activity 的时候就展示了动画效果:
动画的效果是通过 overridePendingTransition 方法实现的,那么下面我们来看一下 overridePendingTransition 方法的定义,我们在 overridependingTransition 方法在定义的时候有这样的一段注释说明:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">/** * 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. */
好吧,这段注释,告诉通过注释我们能够知道:
好吧,本着批判的精神,我们来看一下是不是这样的,首先看一下如果我们在 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
(2)定义具体的 AppTheme 样式
其中这里的 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);
- }
- });
这时候我们我们执行 diamante 逻辑之后就能发现 activity 在切换的时候出现了动画效果,说明我们设置的 style 起作用了。
(三)使用 ActivityOptions 切换动画实现 Activity 跳转动画
上面我们讲解的通过 overridePendingTransition 方法基本上可以满足我们日常中对 Activity 跳转动画的需求了,但是 MD 风格出来之后,overridePendingTransition 这种老旧、生硬的方式怎么能适合我们的 MD 风格的 App 呢?好在 google 在新的 sdk 中给我们提供了另外一种 Activity 的过度动画——ActivityOptions。并且提供了兼容包——ActivityOptionsCompat。ActivityOptionsCompat 是一个静态类,提供了相应的 Activity 跳转动画效果,通过其可以实现不少炫酷的动画效果。
(1)在跳转的 Activity 中设置 contentFeature
- @Override protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState); // 设置contentFeature,可使用切换动画 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); Transition explode = TransitionInflater.from(this).inflateTransition(Android.R.transition.explode); getWindow().setEnterTransition(explode); setContentView(R.layout.activity_three); }
这里我们在 Activity 的 setContentView 之前调用了:
- getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
方法,看过我的 Activity 布局加载流程的同学应该知道,这里的 setFeature 就是为 activity 的窗口设置特性,不同的特性对应不同的布局方式,比如可以设置无 toolbar 模式,有 toolbar 模式等等。而这里设置的是需要过渡动画,并且我们获取了 Android 中内置的 explode 动画,并设值给了 Activity 的 window 窗口对象,这样当 Activity 被启动的时候就会执行 explode 所带便的动画效果了。
(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 的方式
这种方式其实就是通过 style 的方式展示和使用 ActivityOptions 过度动画,下面是实现通过定义 style 方式定义过度动画的步骤:
(1)编写过度动画文件
首先我们需要在 Application 项目 res 目录下新建一个 transition 目录,然后创建资源文件,然后使用这些系统自带的过渡动画效果,这里设置了过度时长为 300ms。
(2)定义 style 文件
在 Application 的 style 文件中添加:
- @transition / activity_explode@transition / activity_explode
并指定过渡动画效果为我们刚刚定义的过渡动画文件。
(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 跳转过度动画了,其和通过代码方式实现的效果是类似的,而且这种动画效果是全局的。
(五)使用 ActivityOptions 动画共享组件的方式实现跳转 Activity 动画
这里的共享组件动画效果是指将前面一个 Activity 的某个子 View 与后面一个 Activity 的某个子 View 之间有过渡效果,即在这种过度效果下实现 Activity 的跳转操作。那么如何实现两个组件 View 之间实现过渡效果呢?
(1)定义共享组件
在 Activity a 中的 button 按钮点击 transitionName 属性:
- 在Activity b的布局文件中为组件定义transitionName属性,这样这两个组件相当于有了过度对应关系,这里需要注意的是这两个组件的transitionName属性的值必须是相同的。
(2)调用 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 中组件的过度效果。
总结:
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2016/12-05/13909380.html