曾經的Android在Activity進行跳轉的時候,只是非常生硬的切換,即使通過overridePendingtransition(int inIn,int outId)這個方法來給Activity增加一些切換動畫,效果也只是差強人意。而在Android5.X中,Google對動畫效果進行了更深一步的詮釋,爲Activity的轉場設計了更加豐富的動畫效果。
Android 5.X提供了三種Transition類型。
- 進入:一個進入的過渡動畫決定Activity中所有的視圖怎麼進入屏幕。
- 退出:一個退出的過渡動畫決定一個Activity中所有視圖怎麼退出屏幕。
- 共享元素:一個共享元素通過過渡動畫決定兩個Activities之間的過渡,怎麼共享它們的視圖。
其中,進入和退出效果包括:
- explode(分解)——從屏幕中間進或出,移動視圖。
- slide(滑動)——從屏幕邊緣進或者出,移動視圖。
- fade(淡出)——通過改變屏幕上視圖的不透明度達到添加或者移除視圖。
共享元素包括:
- changeBounds——改變目標視圖的邊界佈局。
- changeClipBounds——裁剪目標視圖的邊界。
- changeTransFrom——改變目標視圖的縮放比例和旋轉角度
- changeImageTransfrom——改變目標圖形的大小和縮放比例。
可以發現,在Android 5.X上,動畫效果的種類變得更加豐富了。
首先來看看普通的三種Activity過渡動畫,要使用這些動畫非常簡單,例如從ActivityA跳轉到ActivityB,只需要在ActivityA中將基本的startActivity(intent)方法改爲如下代碼即可。
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
而在ActivityB中,只需要設置如下所示代碼,注意此代碼必須放在setContentView()之前,否則會報異常。
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
或者在樣式文件中設置如下所示代碼。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<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:windowContentTransitions">true</item>
</style>
</resources>
接下來就可以在ActivityB中設置進入它的具體動畫了,代碼如下所示。
getWindow().setEnterTransition(new Explode());
getWindow().setEnterTransition(new Fade());
getWindow().setEnterTransition(new Slide());
或者通過如下代碼來設置離開ActivityB的動畫效果。
getWindow().setExitTransition(new Slide());
getWindow().setExitTransition(new Fade());
getWindow().setExitTransition(new Explode());
完整代碼如下所示。
public class A_ActivityTransitionActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transition);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void btnStartB(View view) {
Intent intent = new Intent(this, B_ActivityTransitionActivity.class);
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
}
}
public class B_ActivityTransitionActivity extends AppCompatActivity {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
setContentView(R.layout.activity_b__transition);
getWindow().setEnterTransition(new Explode());
getWindow().setExitTransition(new Explode());
// getWindow().setEnterTransition(new Fade());
// getWindow().setExitTransition(new Fade());
//
// getWindow().setEnterTransition(new Slide());
// getWindow().setExitTransition(new Slide());
}
}
而對於共享元素的動畫效果,可以藉助開發者網站上的一張圖來幫助理解,如下所示
第一張圖中的Android機器人就是共享元素,即Activity1和Activity2都擁有的元素,只是在Activity2中對Android機器人進行了強調,所以視圖被方法,在Activity1跳轉到Activity2的時候,其他的元素小時,而共享元素——Android機器人通過動畫效果直接顯示到ACtivity2中,這個動畫效果在Google IO大會的App上已經有了非常好的展示效果,感興趣的讀者可以下載Google IO App來觀看效果。
想要在程序中使用共享原色的動畫效果也非常簡單,首先需要在ACtivity1的佈局文件中設置共享的元素,給他增加相應的屬性,如下所示。
android:transitionName="XXX"
同樣在Activity2的佈局文件中,給要實現共享效果的元素也增加相同的屬性,代碼如下所示。
android:transitionName="XXX"
這裏需要注意的是一定要保證命名相同,這樣系統才能找到共享元素。
如果只要一個元素,那麼在Activity1中只需要使用如下代碼。
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, view, "share").toBundle());
如果有多個共享的元素,那麼可以通過Pair.create()來創建多個共享元素,代碼如下所示。
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this,
Pair.create(view, "share"),
Pair.create(fab, "fab")).toBundle());
下面通過一個實例來演示Activity的過渡公話,Activity1代碼如下所示。
package test.chenj.study_12;
import android.annotation.TargetApi;
import android.app.ActivityOptions;
import android.content.Intent;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Pair;
import android.view.View;
public class A_ActivityTransitionActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transition);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void btnStartB(View view) {
Intent intent = new Intent(this, B_ActivityTransitionActivity.class);
// startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, view, "share").toBundle());
}
}
XML代碼如下所示。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.chenj.study_12.A_ActivityTransitionActivity">
<ImageView
android:onClick="btnStartB"
android:src="@mipmap/ic_launcher"
android:transitionName="share"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
ActivityB代碼如下所示。
package test.chenj.study_12;
import android.annotation.TargetApi;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.transition.Explode;
import android.transition.Fade;
import android.transition.Slide;
import android.view.View;
import android.view.Window;
public class B_ActivityTransitionActivity extends AppCompatActivity {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b__transition);
// getWindow().setEnterTransition(new Explode());
// getWindow().setExitTransition(new Explode());
// getWindow().setEnterTransition(new Fade());
// getWindow().setExitTransition(new Fade());
//
// getWindow().setEnterTransition(new Slide());
// getWindow().setExitTransition(new Slide());
}
}
XML代碼如下所示。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.chenj.study_12.B_ActivityTransitionActivity">
<ImageView
android:transitionName="share"
android:src="@mipmap/ic_launcher"
android:layout_centerInParent="true"
android:layout_width="200dp"
android:layout_height="200dp" />
</RelativeLayout>
實際運行效果如圖所示。
由於本實例設計很懂動態效果,所以很難在書本上讓讀者體驗到實際效果,希望讀者能實際運行一下本實例,體驗
Android5.X中的Activity轉場動畫效果。