引子
相信開發過iOS的程序員都知道iOS ViewController之間的跳轉動畫非常多,很酷對不對?這讓開發Android的羡慕不已,曾幾何時,Android中的Activity跳轉是何等的生硬,But,在Android 5.0以后,Google也為Activity的轉場設計了更加友好的動畫效果。
轉場動畫(Activity Transition)基本介紹
Android 5.0 提供了三種Transition類型
進入:決定Activity中的所有的視圖怎么進入屏幕。
退出:決定一個Activity中的所有視圖怎么退出屏幕。
共享元素:決定兩個activities之間的過渡,怎么共享(它們)的視圖。
進入和退出包含如下動畫效果
- explode(分解) – 從屏幕中間進或出
- slide(滑動) - 從屏幕邊緣進或出地
- fade(淡出) –通過改變屏幕上視圖的不透明度達到添加或者移除視圖的效果
共享元素包含如下動畫效果
- changeBounds - 改變目標視圖的布局邊界
- changeClipBounds - 裁剪目標視圖邊界
- changeTransform - 改變目標視圖的縮放比例和旋轉角度
- changeImageTransform - 改變目標圖片的大小和縮放比例
實踐
1.准備好2個Activity的布局,弄幾個按鈕,分別對應幾種轉場動畫。
activity_one.xml ActivityOne的布局,其中最后一個Button是為了做共享元素動畫
<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:background="#ff0000" android:gravity="center" android:orientation="vertical" tools:context=".MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:onClick="explode" android:text="explode" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:onClick="slide" android:text="slide" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:onClick="fade" android:text="fade" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:onClick="share" android:text="share" /> <Button android:id="@+id/share" android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:background="@drawable/football" /> </LinearLayout>
activity_two.xml ActivityTwo的布局,里面的Button與第一個布局中的最后一個Button呼應,只是大小不一樣
<RelativeLayout 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:background="#0000ff" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <Button android:id="@+id/share" android:layout_width="wrap_content" android:layout_height="wrap_content" android:transitionName="shareTransition" android:layout_gravity="center_horizontal" android:background="@drawable/football" android:layout_centerInParent="true" android:onClick="share" /> </RelativeLayout>
2.ActivityOne 與 ActivityTwo
ActivityOne.java
public class ActivityOne extends Activity { private Intent intent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_one); intent = new Intent(ActivityOne.this, ActivityTwo.class); } public void explode(View view) { intent.putExtra("transition", "explode"); //將原先的跳轉改成如下方式 startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(ActivityOne.this).toBundle()); } public void slide(View view) { intent.putExtra("transition", "slide"); //將原先的跳轉改成如下方式 startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(ActivityOne.this).toBundle()); } public void fade(View view) { intent.putExtra("transition", "fade"); //將原先的跳轉改成如下方式 startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(ActivityOne.this).toBundle()); } public void share(View view) { //共享元素 Button share = (Button) findViewById(R.id.share); intent.putExtra("transition", "share"); //將原先的跳轉改成如下方式,注意這里面的第三個參數決定了ActivityTwo 布局中的android:transitionName的值,它們要保持一致 startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(ActivityOne.this, share, "shareTransition").toBundle()); } }
ActivityTwo.java
public class ActivityTwo extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 允許使用transitions getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); String transition = getIntent().getStringExtra("transition"); switch (transition) { case "explode": // 設置進入時進入動畫 Explode explode = new Explode(); explode.setDuration(1000); getWindow().setEnterTransition(explode); break; case "slide": Slide slide = new Slide(); slide.setDuration(1000); getWindow().setEnterTransition(slide); break; case "fade": Fade fade = new Fade(); fade.setDuration(1000); getWindow().setEnterTransition(fade); break; case "share": break; } // 所有操作在設置內容視圖之前 setContentView(R.layout.activity_two); } }
說明:getWindow().setEnterTransition()
是進入動畫,與之對應的getWindow().setExitTransition()
就是退出轉場動畫,用法和上面一樣,就不重復了
3.測試效果
explode

explode.gif
slide

slide.gif
fade

fade.gif
share

share.gif
問題
explode效果感覺並沒有從中間進,而是從上面下來的,這是為什么呢?歡迎知道的告知,感謝。