Android動畫了解—轉場/過渡(Transition) 動畫

轉場/過渡(Transition) 動畫

Transition 是指不同 UI 狀態轉換時的動畫。
在這裏插入圖片描述
在這裏插入圖片描述

界面過渡

界面 的 過渡 可以 分爲 進入/出場 的過渡動畫

設置進場/出場/返回/重新進入 的過渡場動畫:

  • Window.setEnterTransition(Transition transition) 設置進場動畫 主界面-(跳轉)->A,A 進入過渡
  • Window.setExitTransition(Transition transition) 設置出場動畫 A-(跳轉)->B,A 出場過渡
  • Window.setReturnTransition(Transition transition) 設置返回動畫 A-(返回)->主界面,A 出場過渡
  • Window.setReenterTransition(Transition transition) 設置重新進入動畫 B-(返回)->A,A 進入過渡
  • setAllowEnterTransitionOverlap():是否運行佈局顯示時重疊
  • setAllowReturnTransitionOverlap():是否運行佈局顯示時重疊

在這裏插入圖片描述
來看一個界面過渡的動畫效果小栗子
在這裏插入圖片描述

看下小栗子代碼

// 過渡效果
Explode explode = new Explode(); // 從屏幕中間進入或退出,移動視圖
explode.setInterpolator() // 設置插值器
expload.setDuration(1000) // 過渡動效執行時間
// 主界面
getWindow().setReenterTransition(explode);  // 重新進入
getWindow().setExitTransition(explode); // 出場
// 界面A
getWindow().setReenterTransition(explode); // 重新進入
getWindow().setExitTransition(explode); // 出場
getWindow().setReturnTransition(explode); // 返回
getWindow().setEnterTransition(explode); // 進入
//界面B
getWindow().setEnterTransition(explode);
getWindow().setReturnTransition(explode);

// 啓動Activity,讓過渡動畫生效
ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(TransitionManagerActivity.this);
startActivity(intent, activityOptions.toBundle());

相關知識點1(過渡transition效果)
進入/出場/重新進入/返回過渡效果(這三個類都繼承於 Transition ,有一些相同的屬性 setDuration,setInterpolator)

  • Explode(分解):從場景的中心移入或移出 官方API資料
  • Slide(滑動):從場景的邊緣移入或移出,滑動 (Gravity 可以設置方向 LEFT, TOP等), [官方API資料] (https://developer.android.google.cn/reference/android/support/transition/Slide)
  • Fade(淡出):調整透明度產生漸變效果 官方API資料
    在這裏插入圖片描述

xml方式的過渡效果,類似前面章節動畫的XML文件

Transition explode = TransitionInflater.from(this).inflateTransition(R.transition.new_explode);
// 存放的目錄爲 res/transition/new_explode.xml
<explode xmlns:android="http://schemas.android.com/apk/res/android"
 android:interpolator="@android:interpolator/插值器"
 android:duration="2000" />

主題Style設置

舉個栗子:
<style name="AppTheme" parent="Theme.xxxx.xxxx">
	<item name="android:windowExitTransition">@transition/new_explode</item>
	<item name="android:windowEnterAnimation">@transition/new_explode</item>
    <item name="android:windowReenterTransition">@transition/new_explode</item>
    <item name="android:windowReturnTransition">@transition/new_explode</item>
</style>

相關知識點2(ActivityOptions)

  • makeSceneTransitionAnimation(Activity activity, Pair<View, String>... sharedElements) - 用在共享,expolad,slide,fade 上
  • makeCustomAnimation(Context context, int enterResId, int exitResId) - 使用自定義的xml動畫
  • makeScaleUpAnimation(View source, int startX, int startY, int width, int height) - 從指定大小放大到最大顯示
  • makeClipRevealAnimation(View source, int startX, int startY, int width, int height) - 從一個點以圓形漸變到滿屏
  • makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY) - 縮略圖形縮放轉場動畫

ActivityOptions的小栗子
makeSceneTransitionAnimation
這個在前面已經使用過,後續會講解的 共享元素界面過渡 的小栗子

makeCustomAnimation 自定義 進入,退出動畫
在這裏插入圖片描述

# 從 界面A(exit:no_anim) 進入 界面B(enter:enter_up)
ActivityOptionsCompat.makeCustomAnimation(this, R.anim.enter_up, R.anim.no_anim);

# 界面B enter:res/anim/enter_up.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="10000">
    <translate android:fromYDelta="100%p"/>
    <translate android:toYDelta="0%p"/>
</set>

# 界面A exit:res/anim/no_anim.xml
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="1.0"
    android:toAlpha="0.1"
    android:duration="10000" />

makeScaleUpAnimation | makeClipRevealAnimation | makeThumbnailScaleUpAnimation
這三種是系統提供的默認動畫效果, 我實際使用感覺效果不是很明顯, 感覺用處不大.
感興趣的同學可以自行搜索

  • makeScaleUpAnimation:比如 界面A 點擊某個View,打開B頁面,B頁面會以相對於View的某個位置放大展開。
    在這裏插入圖片描述
ActivityOptions options = ActivityOptions.makeScaleUpAnimation(
	view, 0, 0, //拉伸開始的座標
	view.getMeasuredWidth(), view.getMeasuredHeight()); // 初始的寬高
startActivity(intent, options.toBundle());
  • makeClipRevealAnimation:跳轉新頁面時,新頁面的剪切範圍逐漸擴大,直到完全顯示。(從一個點以圓形漸變到滿屏)

  • makeThumbnailScaleUpAnimation:切換時,會先顯示一個Bitmap,再過渡到新的頁面。
    在這裏插入圖片描述

Bitmap bitmap = view.getDrawingCache();
ActivityOptions options = ActivityOptions.makeThumbnailScaleUpAnimation(view, bitmap, 0, 0);
startActivity(intent, options.toBundle());

相關知識點3(過渡transition效果2)

  • ChangeBounds - 檢測view的位置邊界創建移動和縮放 過渡動畫
  • ChangeClipBounds - 檢測view的scale和rotation創建縮放和旋轉動畫
  • ChangeTransform - 檢測view的剪切區域的位置邊界,和ChangeBounds類似。不過ChangeBounds針對的是view而ChangeClipBounds針對的是view的剪切區域(setClipBound(Rect rect) 中的rect)。如果沒有設置則沒有動畫效果
  • ChangeImageTransform - 檢測ImageView(這裏是專指ImageView)的尺寸,位置以及ScaleType,並創建相應動畫。
    以上的 繼承Transiton類
    後續的佈局場景切換會使用這個知識點來講解.

參考資料

自定義transition
當然你可以繼承Transition,編寫自己的自定義 Transition. 感興趣的同學可以自行搜索相關資料.

public class CustomTransition extends Transition {

    @Override
    public void captureStartValues(TransitionValues values) {}

    @Override
    public void captureEndValues(TransitionValues values) {}

    @Override
    public Animator createAnimator(ViewGroup sceneRoot,
                                   TransitionValues startValues,
                                   TransitionValues endValues) {}
}

場景小劇場

這裏可以看看 Launcher3 startActivity 的使用,啓動第三方的應用,保持了統一的啓動過渡動畫,它的方式也是安全啓動的代碼;

建議編寫電視相關的桌面的時候按照Launcher3的方式來寫.

在這裏插入圖片描述
在這裏插入圖片描述
代碼片段
在這裏插入圖片描述

共享元素界面過渡

從一個界面 跳轉 到 一個新的界面,界面元素 過渡 到 新界面的元素上.
在這裏插入圖片描述 在這裏插入圖片描述 在這裏插入圖片描述
如何去實現共享元素的過渡的動畫效果

比如 Activity1 跳轉到 Activity2,共享元素 view1->view2:

爲兩個頁面的共享元素指定同樣 的 transitionName

# Activity1,你需要設置 view1 的 transitionName 的名稱爲 "ShardTest"
Intent intent = new Intent(this, Activity2.class);
ActivityOptions options = ActivityOptions
	.makeSceneTransitionAnimation(this, view1, "ShardTest");
startActivity(intent, options.toBundle());
# activity2 的 view2 需要和 Activity2 的 view1 的 transitionName 的名稱保持一致.
1. 代碼中使用(代碼中使用View.setTransitionName(String)方法)
ViewCompat.setTransitionName(view2, "ShardTest");
2. 佈局XML中指定(在佈局文件中使用android:transitionName屬性)
android:transitionName="robot"

如果界面上又多個共享元素,要如何寫?

如果有多個共享元素,也可以使用下面的方式:

Pair.create(view2, "ShardTestOne")
new Pair<View, String>(view2, "ShardTestOne")

ActivityOptionsCompat.makeSceneTransitionAnimation(this,
	Pair.create(view1, "ShardTestOne"), 
	Pair.create(view11, "ShardTestTwo"));

在另外一端,也需要處理多個共享元素:

ViewCompat.setTransitionName(view2, "ShardTestOne");
ViewCompat.setTransitionName(view22, "ShardTestTwo");
// 或者佈局中指定(android:transitionName),這裏不過多解釋,同上

看看效果,這就是imageview與TextView共享元素的效果
在這裏插入圖片描述

電視系統中 SystemUI 最近任務的共享元素的過渡動畫效果 栗子,可以看看效果(從系統設置的界面到最近任務界面的縮略圖佈局)
在這裏插入圖片描述

TranstionManger + Screne(場景) 佈局過渡

Android L(api19) 引入的場景(Scene)動畫的擴展. 使開發者更加方便的實現佈局(界面)變化時候的過渡動畫.

相關API:

  • Scene.getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context) 根據佈局ID,加載一個場景
  • Scene(ViewGroup sceneRoot, View view) 根據 view, 加載一個場景
  • TransitionManager.go(Scene scene, Transition transition) 切換場景佈局
  • TransitionManager.beginDelayedTransition 保存一個當前視圖樹狀態的場景,

參考官方的API文檔

舉幾個小栗子

兩個佈局的過渡

// 從佈局生成場景(Scene)
final Scene scene1 = Scene.getSceneForLayout(container, R.layout.scene1_layout, context);
// View scene1Layout = LayoutInflater.from(context).inflate(R.layout.scene1_layout, null);
final Scene scene2 = Scene.getSceneForLayout(container, R.layout.scene2_layout/*scene1Layout*/, context);
TransitionManager.go(scene1, new Fade()); // fade_in 淡入視圖,fade_out 淡出視圖,fade_in_out(默認)
TransitionManager.go(scene2, new Fade());

在這裏插入圖片描述
一個界面中的兩個 view 過渡

final Scene scene1 = new Scene(containerView, imageview1);
final Scene scene2 = new Scene(container, imageview2);
TransitionManager.go(scene1, transition);
TransitionManager.go(scene2, transition);

在這裏插入圖片描述

控件的屬性改變的過渡

ChangeBounds transition = new ChangeBounds();
// 執行TransitionManager.beginDelayedTransition後,會保存一個當前視圖樹狀態的場景
TransitionManager.beginDelayedTransition(containerView, transition);
// 
ViewGroup.LayoutParams lp = containerView.getLayoutParams();
lp.width = 200; // width = 500;
lp.height = 200; // height = 500;
container.setLayoutParams(lp);

在這裏插入圖片描述
在這裏插入圖片描述

如果上面的栗子不太直觀,可以看看其它的效果(改變了寬高,隱藏,顯示 屬性,使用的 explode + Changebounds)
在這裏插入圖片描述

可以使用XML方式加載過渡效果

Transition transition = TransitionInflater.from(context).inflateTransition(R.transition
                        .test_trantion);

// test_trantion.xml
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1500"
    android:interpolator="@android:interpolator/decelerate_cubic">
    <changeBounds />
    <explode />
</transitionSet>

再看一個 Changebounds 小栗子效果
在這裏插入圖片描述

相關DEMO代碼

感興趣的小夥伴 查詢 官方資料 或者 搜索相關資料

也可以瞭解 最新的 佈局過渡 ConstraintLayout 2.0 的 motionlayout

在這裏插入圖片描述


注意

1.從 Activity1 跳轉到 Activity2 的後,如果要退出 Activity2 ,調用 Activity.finishAfterTransition(),不要調用 Activity.finish().
不然沒有從 Activity2 回到 Activity1 的動畫效果.

2.如果不生效可以加入支持

// 1. 主題
<item name="android:windowContentTransitions">true</item>
// 2. 代碼加入,記得要在 setContentView 之前加.
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
setContentView(R.layout.activity_start_anim);

3.Overlay的具體效果不太明白,但是從語義來說應該是讓動畫更加的融合自然。禁用(false)/開啓(true) 默認效果
getWindow().setSharedElementsUseOverlay(true);

參考資料

谷歌過渡動畫指南
過渡動畫視頻1
過渡動畫視頻2
高逼格Android轉場動畫
Android轉場動畫和共享元素動畫兼容5.0以下版本的實現
動起來!動起來!- Android Transitions 轉場動畫
Android炫酷的Activity切換效果,共享元素
Android動畫之Transition和TransitionManager使用
Android Transition Framework詳解—超炫的動畫框架
A beginners guide to implement Android Animations (Part 2)
Animate all the things. Transitions in Android
程序員與設計/動效師的溝通工具


Android動畫了解—屬性動畫(Property Animation)<=上個章節 下個章節=> Android動畫了解—RecyclerView Animator

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章