• 12.7 Activity过渡动画" level="2">12.7 Activity过渡动画

    12.7 Activity过渡动画" class="reference-link">12.7 Activity过渡动画

    曾经的Android在Activity进行跳转的时候,只是非常生硬的切换,即使通过overridePendingtransition(int inId, int outId)这个方法来给Activity增加一些切换动画,效果也只是差强人意。而在Android 5.X中,Google对动画效果进行了更深一步的诠释,为Activity的转场效果设计了更加丰富的动画效果。

    1. Android 5.X提供了三种Transition类型。
    • 进入:一个进入的过渡动画决定Activity中的所有的视图怎么进入屏幕。
    • 退出:一个退出的过渡动画决定一个Activity中的所有视图怎么退出屏幕。
    • 共享元素:一个共享元素过渡动画决定两个Activities之间的过渡,怎么共享它们的视图。

    其中,进入和退出效果包括:

    • explode(分解)——从屏幕中间进或出,移动视图
    • slide(滑动)——从屏幕边缘进或出,移动视图
    • fade(淡出)——通过改变屏幕上视图的不透明度达到添加或者移除视图

    共享元素包括:

    • changeBounds——改变目标视图的布局边界
    • changeClipBounds——裁剪目标视图边界
    • changeTransform——改变目标视图的缩放比例和旋转角度
    • changeImageTransform——改变目标图片的大小和缩放比例

    可以发现,在Android 5.X上,动画效果的种类变得更加丰富了。

    首先来看看普通的三种Activity过渡动画,要使用这些动画非常简单,例如从ActivityA跳转到ActivityB,只需要在ActivityA中将基本的startActivity(intent)方法改为如下代码即可。

    1. startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this). toBundle());

    而在ActivityB中,只需要设置下如下所示代码。

    1. getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

    或者在样式文件中设置如下所示代码。

    1. <item name="android:windowContentTransitions">true</item>

    那么接下来就可以设置进入ActivityB的具体的动画效果了,代码如下所示。

    1. getWindow().setEnterTransition(new Explode());
    2. getWindow().setEnterTransition(new Slide());
    3. getWindow().setEnterTransition(new Fade());

    或者通过如下代码来设置离开ActivityB的动画效果。

    1. getWindow().setExitTransition (new Explode());
    2. getWindow().setExitTransition (new Slide());
    3. getWindow().setExitTransition (new Fade());

    而对于共享元素的动画效果,可以借用开发者网站上的一张图来帮助大家理解,如图12.16所示。

    12.7 Activity过渡动画 - 图1 图12.16 共享元素转场动画</h4>

    第一张图中的Android机器人就是共享元素,即Activity1和Activity2都拥有的元素,只是在Activity2中对Android机器人进行了强调,所以视图被放大,在Activity1跳转到Activity2的时候,其他元素消失,而共享元素——Android机器人通过动画效果直接显示到Activity2中,这个动画效果在Google IO大会的App上已经有了非常好的展示效果,感兴趣的读者可以下载Google IO App来观看其效果。

    要想在程序中使用共享元素的动画效果也非常简单,首先需要在Activity1的布局文件中设置共享的元素,给它增加相应的属性,代码如下所示。

    1. android:transitionName="XXX"

    同时在Activity2的布局文件中,给要实现共享效果的元素也增加相同的属性,代码如下所示。

    1. android:transitionName="XXX"

    这里需要注意的是一定要保证命名相同,这样系统才能找到共享元素。

    如果只要一个共享元素,那么在Activity1中只需要使用如下代码。

    1. startActivity(intent,
    2. ActivityOptions.makeSceneTransitionAnimation(
    3. this,
    4. view,
    5. "share").toBundle());

    使用的参数就是在前面普通动画的基础上增加了共享的View和前面取的名字。

    如果有多个共享的元素,那么可以通过Pair.create()来创建多个共享元素,代码如下所示。

    1. startActivity(intent,
    2. ActivityOptions.makeSceneTransitionAnimation(
    3. this,
    4. Pair.create(view, "share"),
    5. Pair.create(fab, "fab")).toBundle());

    下面通过一个实例来演示Activity的过渡动画,Activity1代码如下所示。

    1. package com.yishengxu.myapplication;
    2.  
    3. import android.app.Activity;
    4. import android.app.ActivityOptions;
    5. import android.content.Intent;
    6. import android.os.Bundle;
    7. import android.util.Pair;
    8. import android.view.View;
    9.  
    10.  
    11. public class MainActivity extends Activity {
    12.  
    13. private Intent intent;
    14.  
    15. @Override
    16. protected void onCreate(Bundle savedInstanceState) {
    17. super.onCreate(savedInstanceState);
    18. setContentView(R.layout.activity_transition);
    19. }
    20.  
    21. //设置不同动画效果
    22. public void explode(View view) {
    23. intent = new Intent(this, Transitions.class);
    24. intent.putExtra("flag", 0);
    25. startActivity(intent,
    26. ActivityOptions.makeSceneTransitionAnimation(this)
    27. .toBundle());
    28. }
    29. //设置不同动画效果
    30. public void slide(View view) {
    31. intent = new Intent(this, Transitions.class);
    32. intent.putExtra("flag", 1);
    33. startActivity(intent,
    34. ActivityOptions.makeSceneTransitionAnimation(this)
    35. .toBundle());
    36. }
    37.  
    38. //设置不同动画效果
    39. public void fade(View view) {
    40. intent = new Intent(this, Transitions.class);
    41. intent.putExtra("flag", 2);
    42. startActivity(intent,
    43. ActivityOptions.makeSceneTransitionAnimation(this)
    44. .toBundle());
    45. }
    46. //设置不同动画效果
    47. public void share(View view) {
    48. View fab = findViewById(R.id.fab_button);
    49. intent = new Intent(this, Transitions.class);
    50. intent.putExtra("flag", 3);
    51. //创建单个共享元素
    52. // startActivity(intent,
    53. // ActivityOptions.makeSceneTransitionAnimation(
    54. // this, view, "share").toBundle());
    55. startActivity(intent,
    56. ActivityOptions.makeSceneTransitionAnimation(
    57. this,
    58. //创建多个共享元素
    59. Pair.create(view, "share"),
    60. Pair.create(fab, "fab")).toBundle());
    61. }
    62. }

    XML代码如下所示。

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. android:layout_width="match_parent"
    4. android:orientation="vertical"
    5. android:layout_height="match_parent">
    6.  
    7. <Button
    8. android:layout_width="match_parent"
    9. android:layout_height="100dp"
    10. android:onClick="explode"
    11. android:text="explode" />
    12.  
    13. <Button
    14. android:layout_width="match_parent"
    15. android:layout_height="100dp"
    16. android:onClick="slide"
    17. android:text="slide" />
    18.  
    19. <Button
    20. android:layout_width="match_parent"
    21. android:layout_height="100dp"
    22. android:onClick="fade"
    23. android:text="fade" />
    24.  
    25. <Button
    26. android:layout_width="match_parent"
    27. android:layout_height="100dp"
    28. android:transitionName="share"
    29. android:onClick="share"
    30. android:text="share" />
    31.  
    32. <Button
    33. android:id="@+id/fab_button"
    34. android:layout_width="56dp"
    35. android:transitionName="fab"
    36. android:layout_height="56dp"
    37. android:background="@drawable/ripple_round"
    38. android:elevation="5dp"/>
    39. </LinearLayout>

    ActivityB代码如下所示。

    1. package com.yishengxu.myapplication;
    2.  
    3. import android.app.Activity;
    4. import android.os.Bundle;
    5. import android.transition.Explode;
    6. import android.transition.Fade;
    7. import android.transition.Slide;
    8. import android.view.Window;
    9.  
    10. public class Transitions extends Activity {
    11.  
    12. @Override
    13. protected void onCreate(Bundle savedInstanceState) {
    14. super.onCreate(savedInstanceState);
    15. getWindow().requestFeature(
    16. Window.FEATURE_CONTENT_TRANSITIONS);
    17. int flag = getIntent().getExtras().getInt("flag");
    18. //设置不同的动画效果
    19. switch (flag) {
    20. case 0:
    21. getWindow().setEnterTransition(new Explode());
    22. break;
    23. case 1:
    24. getWindow().setEnterTransition(new Slide());
    25. break;
    26. case 2:
    27. getWindow().setEnterTransition(new Fade());
    28. getWindow().setExitTransition(new Fade());
    29. break;
    30. case 3:
    31. break;
    32. }
    33. setContentView(R.layout.activity_transition_to);
    34.  
    35. }
    36. }

    XML代码如下所示:

    1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2. xmlns:tools="http://schemas.android.com/tools"
    3. android:layout_width="match_parent"
    4. android:layout_height="match_parent"
    5. android:paddingBottom="@dimen/activity_vertical_margin"
    6. tools:context=".MyActivity">
    7.  
    8. <View
    9. android:id="@+id/holder_view"
    10. android:layout_width="match_parent"
    11. android:layout_height="300dp"
    12. android:transitionName="share"
    13. android:background="?android:colorPrimary" />
    14.  
    15. <Button xmlns:android="http://schemas.android.com/apk/res/android"
    16. android:id="@+id/fab_button"
    17. android:transitionName="fab"
    18. android:layout_width="56dp"
    19. android:layout_height="56dp"
    20. android:layout_marginRight="@dimen/activity_horizontal_margin"
    21. android:background="@drawable/ripple_round"
    22. android:elevation="5dp"
    23. android:layout_below="@+id/holder_view"
    24. android:layout_marginTop="-26dp"
    25. android:layout_alignParentEnd="true" />
    26.  
    27. <RelativeLayout
    28. android:layout_width="match_parent"
    29. android:layout_height="match_parent"
    30. android:paddingTop="10dp"
    31.  
    32. android:layout_below="@id/holder_view">
    33.  
    34. <Button
    35. android:layout_width="match_parent"
    36. android:layout_height="60dp"
    37. android:id="@+id/button"
    38. android:layout_below="@+id/button4"
    39. android:layout_marginTop="10dp" />
    40.  
    41. <Button
    42. android:layout_width="match_parent"
    43. android:layout_height="60dp"
    44. android:layout_marginTop="10dp"
    45. android:id="@+id/button4"
    46. android:layout_alignParentStart="true" />
    47.  
    48. </RelativeLayout>
    49. </RelativeLayout>

    程序运行效果如图12.17、图12.18所示。

    12.7 Activity过渡动画 - 图2 12.7 Activity过渡动画 - 图3
    图12.17 转场动画效果演示(前) 图12.18转场动画效果演示(后)

    由于本实例涉及很多动态效果,所以很难在书本上让读者体验到实际效果,所以希望读者能实际运行一下本实例,体验Android 5.X中的Activity转场动画效果。