1. 程式人生 > >【Transition】Android炫酷的Activity切換效果,共享元素

【Transition】Android炫酷的Activity切換效果,共享元素

本文原專案地址為:
https://github.com/lgvalle/Material-Animations
在文章最後,有我自己對著這個專案手敲的一份。
程式碼基本一模一樣,只有略微的修改,加了一些註釋,以及將其中大多數英文翻譯成了中文。

此篇 API 均為 Android 5.0(API 級別 21) 以上才可支援。
此demo一共分為四部分:

1.1 普通過渡 Transition;
1.2 Shared Elements Transition 共享元素;
2.0 TransitionManager 控制動畫;
3.0 ViewAnimationUtils 顯示或隱藏效果。

過渡效果 Transition

Material Design 為應用中的切換頁面時,提供了非常優雅的視覺切換效果。
您可為進入、退出轉換、頁面之間的共享元素轉換設定特定的動畫。

1. Transition 動畫都包含哪些?

Android 5.0(API 級別 21)支援的進入與退出轉換有三個:

Explode Slide Fade
從中心移入或移出 從邊緣移入或移出 調整透明度產生漸變



一會看到使用場景的時候,就會發現上面的三張圖,每張圖都經歷了:(此處可以一會再回過頭來看)

退出 -> 進入  -> 返回   -> 重新進入
Exit -> Enter -> Return
-> Reenter **第一個頁面設定:** android:windowExitTransition 啟動新 Activity ,此頁面退出的動畫 android:windowReenterTransition 重新進入的動畫。即第二次進入,可以和首次進入不一樣。 **第二個頁面設定:** android:windowEnterTransition 首次進入顯示的動畫 android:windowReturnTransition 呼叫 finishAfterTransition() 退出時,此頁面退出的動畫 如此即可達到以上效果。

explode:從場景的中心移入或移出
slide:從場景的邊緣移入或移出
fade:調整透明度產生漸變效果

這三個類都繼承於 Transition ,所有有一些屬性都是共同的。
常用屬性如下:

// 設定動畫的時間。型別:long
transition.setDuration();
// 設定修飾動畫,定義動畫的變化率,具體設定往下翻就看到了
transition.setInterpolator();
// 設定動畫開始時間,延遲n毫秒播放。型別:long
transition.setStartDelay();
// 設定動畫的執行路徑
transition.setPathMotion();
// 改變動畫 出現/消失 的模式。Visibility.MODE_IN:進入;Visibility.MODE_OUT:退出。
transition.setMode();

// 設定動畫的監聽事件
transition.addListener()

至於例子,在下一個給出。
喏,這不就是了。

2. 修飾動畫,定義動畫的變化率(Interpolator)

在 Java 程式碼中定義:

Explode transition = new Explode();
transition.setDuration(500);
transition.setInterpolator(new AccelerateInterpolator());

在 Xml 資源定義:

<explode
    android:duration="@integer/anim_duration_long"
    android:interpolator="@android:interpolator/bounce"
    />

可選型別:

AccelerateDecelerateInterpolator 在動畫開始與結束的地方速率改變比較慢,在中間的時候加速

AccelerateInterpolator  在動畫開始的地方速率改變比較慢,然後開始加速

AnticipateInterpolator 開始的時候向後然後向前甩

AnticipateOvershootInterpolator 開始的時候向後然後向前甩一定值後返回最後的值

BounceInterpolator   動畫結束的時候彈起

CycleInterpolator 動畫迴圈播放特定的次數,速率改變沿著正弦曲線

DecelerateInterpolator 在動畫開始的地方快然後慢

LinearInterpolator   以常量速率改變

OvershootInterpolator    向前甩一定值後再回到原來位置
3. 設定 Transition 的時機

到底該什麼時候,設定什麼樣的過渡呢?

以下為動畫的設定場景:

首先開啟頁面A :
頁面A -> Enter 首次進入

從 A 開啟 B :
頁面A -> Exit 退出
頁面B -> Enter 首次進入

從 B 返回 A :
頁面B -> Return 返回
頁面A -> Reenter 重新進入

可設定的方法如下:

android:windowContentTransitions                允許使用transitions

android:windowAllowEnterTransitionOverlap        是否覆蓋執行,其實可以理解成前後兩個頁面是同步執行還是順序執行

android:windowAllowReturnTransitionOverlap        與上面相同。即上一個設定了退出動畫,這個設定了進入動畫,兩者是否同時執行。

android:windowContentTransitionManager            引用TransitionManager XML資源,定義不同視窗內容之間的所需轉換。



android:windowEnterTransition                    首次進入顯示的動畫

android:windowExitTransition                    啟動新 Activity ,此頁面退出的動畫

android:windowReenterTransition                    重新進入的動畫。即第二次進入,可以和首次進入不一樣。

android:windowReturnTransition                    呼叫 finishAfterTransition() 退出時,此頁面退出的動畫



android:windowSharedElementsUseOverlay            指示共享元素在轉換期間是否應使用疊加層。

android:windowSharedElementEnterTransition        首次進入顯示的動畫

android:windowSharedElementExitTransition        啟動新 Activity ,此頁面退出的動畫

android:windowSharedElementReenterTransition    重新進入的動畫。即第二次進入,可以和首次進入不一樣。

android:windowSharedElementReturnTransition        呼叫 finishAfterTransition() 退出時,此頁面退出的動畫

以上為 style 中設定屬性,在程式碼中設定為:

 getWindow().setEnterTransition(visibility);
 // 其餘的都是類似
4. 跳轉頁面

至此,用以上知識基本可以設定出絕大多數的過渡效果。
然後,跳轉頁面跟普通的跳轉也有點不一樣。

跳轉頁面:

protected void transitionTo(Intent i) {
    ActivityOptionsCompat transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(this);
    startActivity(i, transitionActivityOptions.toBundle());
}

退出頁面:

private void closeActivity(){
    // 如果定義了 return transition ,將使用 定義的動畫過渡
    Visibility returnTransition = buildReturnTransition();
    getWindow().setReturnTransition(returnTransition);

    // 如果沒有 return transition 被定義,將使用 反進入 的動畫
    finishAfterTransition();
}

注意:退出時,一定要呼叫:finishAfterTransition();



通過以上設定,就能夠完成一個基本的過渡效果了。

Shared Elements Transition 共享元素

效果如圖:


Shared Elements Transition

共享元素的各種設定 與 普通Transition 差不多。
來說說不同的地方。

攜帶需要共享的 View 進行跳轉

也就是在跳轉的引數中,增加了要共享的 View控制元件。
程式碼如下:

protected void transitionTo(Intent i) {
    ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
                                                    Pair.create(view1, "agreedName1"),
                                                    Pair.create(view2, "agreedName2"));
    startActivity(i, options.toBundle());
}

增加的引數的介紹:

Pair.create(
   View view,      // 本頁面要共享的 View
   String resId    // 下一個頁面的 View 的 id,注意是 id 的字串
頁面切換時,動畫的效果設定

Android 5.0(API 級別 21)支援轉換效果如下:

changeBounds - 改變目標檢視的佈局邊界
changeClipBounds - 裁剪目標檢視邊界
changeTransform - 改變目標檢視的縮放比例和旋轉角度
changeImageTransform - 改變目標圖片的大小和縮放比例

設定程式碼:

Slide slide = new Slide();
slide.setDuration(500);

ChangeBounds changeBounds = new ChangeBounds();
changeBounds.setDuration(500);

getWindow().setEnterTransition(slide);
getWindow().setSharedElementEnterTransition(changeBounds);



Shared Elements Transition 就是 特殊的 Transition 用法,都是一樣的。

TransitionManager 控制動畫

這個框架可以讓一些複雜的動畫特別簡單的被實現。


TransitionManager

簡單的說明一下步驟:

  1. 定義需要切換 layout xml頁面;
  2. 呼叫 Scene.getSceneForLayout() 儲存每個Layout;
  3. 呼叫 TransitionManager.go(scene1, new ChangeBounds()) 切換。

相當於定義了不同的 xml 佈局,然後通過簡單的呼叫,就完成了較為複雜的動畫。

以下為程式碼片段:

private void setupLayout() {
    scene0 = Scene.getSceneForLayout(binding.sceneRoot, R.layout.activity_animations_scene0, this);
    scene1 = Scene.getSceneForLayout(binding.sceneRoot, R.layout.activity_animations_scene1, this);
    scene2 = Scene.getSceneForLayout(binding.sceneRoot, R.layout.activity_animations_scene2, this);
    scene3 = Scene.getSceneForLayout(binding.sceneRoot, R.layout.activity_animations_scene3, this);
    scene4 = Scene.getSceneForLayout(binding.sceneRoot, R.layout.activity_animations_scene4, this);
    binding.sample3Button1.setOnClickListener(this);
    binding.sample3Button2.setOnClickListener(this);
    binding.sample3Button3.setOnClickListener(this);
    binding.sample3Button4.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.sample3_button1:
            TransitionManager.go(scene1, new ChangeBounds());
            break;
        case R.id.sample3_button2:
            TransitionManager.go(scene2, TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds));
            break;
        case R.id.sample3_button3:
            TransitionManager.go(scene3,TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds_sequential));
            break;
        case R.id.sample3_button4:
            TransitionManager.go(scene3,TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds_sequential_with_interpolators));
            break;
    }
}

只需要定義佈局,呼叫調轉,
就實現了,點選四個 Button ,分別切換四個佈局。
TransitionManager.go() 中可以設定各種動畫。

CircularReveal 顯示或隱藏 的效果

ViewAnimationUtils.createCircularReveal()
當您顯示或隱藏一組 UI 元素時,Circular Reveal 可為使用者提供視覺連續性


CircularReveal

引數說明:

Animator createCircularReveal (View view, // 將要變化的 View
            int centerX,                  // 動畫圓的中心的x座標
            int centerY,                  // 動畫圓的中心的y座標
            float startRadius,            // 動畫圓的起始半徑
            float endRadius               // 動畫圓的結束半徑
)

顯示 View :

private void animShow() {
    View myView = findViewById(R.id.my_view);
    // 從 View 的中心開始
    int cx = (myView.getLeft() + myView.getRight()) / 2;
    int cy = (myView.getTop() + myView.getBottom()) / 2;
    int finalRadius = Math.max(myView.getWidth(), myView.getHeight());

    //為此檢視建立動畫設計(起始半徑為零)
    Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
    // 使檢視可見並啟動動畫
    myView.setVisibility(View.VISIBLE);
    anim.start();
}

隱藏 View :

private void animHide() {
    final View myView = findViewById(R.id.my_view);
    int cx = (myView.getLeft() + myView.getRight()) / 2;
    int cy = (myView.getTop() + myView.getBottom()) / 2;

    int initialRadius = myView.getWidth();

    // 半徑 從 viewWidth -> 0
    Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);

    anim.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            myView.setVisibility(View.INVISIBLE);
        }
    });
    anim.start();
}

因為,這些炫酷的效果都只支援 API 23 以上,所以在我們常用的 APP 中都還不常見。但是效果真的很不錯。

值得大家研究一下。
此文是我的一個總結。

這個專案是我對著原專案手敲的,
基本一模一樣,只是加了一些註釋,以及將其中英文翻譯成了中文。
大家可以參考參考。



文/Wing_Li(簡書作者)
原文連結:http://www.jianshu.com/p/a43daa1e3d6e
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。

相關推薦

TransitionAndroidActivity切換效果共享元素

本文原專案地址為:https://github.com/lgvalle/Material-Animations 在文章最後,有我自己對著這個專案手敲的一份。 程式碼基本一模一樣,只有略微的修改,加了一些註釋,以及將其中大多數英文翻譯成了中文。 此篇 API 均為 Andro

BottomBarAndroid的底部切換效果V2.0

本文轉自:http://www.jianshu.com/p/2bafd1bbb21b,,,感謝支援 注意:此庫最低支援版本是 api 11 顯示效果圖: 底部可收回 底部畫面 在平板上顯示會是這個效果 特別炫酷,有木有? 程式碼寫起來也並不難。 跟著程式碼來實現第二

教你用原生CSS寫頁面切換效果跟第三方元件說拜拜

因為專案需要,別人想讓我給他寫一個個人部落格,並且給了我一個其他人的網頁,可以點此檢視。有的同學可能說了,第三方部落格框架這麼多,為什麼還要去手寫的,你說這個有可能是沒有看到開啟這個部落格。 樣式介紹 給大家看一下這個網頁的大體樣式。 這個介面可以說是非常漂亮,整體也是一個響應式佈局,總體來說還算不錯

android筆記移除activity切換效果取消閃爍

最近在做一個音樂播放器遇到了一個問題:如何實現底部固定的迷你播放欄? 首先我考慮的是用一個activity作為container,然後底部播放欄為一個fragment固定在那裡,上面是一些fragment的交替,但這樣做的後整個應用基本上就一個activity

AndroidAndroid開發實現帶有反彈效果仿IOS反彈scrollview詳解教程

作者:程式設計師小冰,GitHub主頁:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 首先給大家看一下我們今天這個最終實現的效果圖: 這個是ios中的反彈效果。當然我

Android進階實現各種各樣的Tab切換效果

一、View  + ViewPager 使用ViewPager和View實現切換效果,效果如下: 主佈局介面: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

RecyclerViewAndroid 橫豎屏切換 超便捷解決方案

相信Android 開發者大多數都遇到過橫豎屏切換的需求,往往最後選擇了鎖定豎屏,或者鎖定橫屏的體驗。或者每次切換螢幕就要切換顯示資料的控制元件。谷歌官方推出的RecyclerView控制元件讓你不再有這樣的煩惱。 最近這兩天又不是很忙了,閒下來看了些關於5.

3Android新建Activity (Eclipse)

原文內容: 在一個Android工程,如何新建一個Activity? 一:新建一個類(*.class),繼承自android.app.Activity類。 二:在res/layout目錄下新建一個佈局xml檔案,檔名隨意(只能包含小寫字母數字或下劃線),用來設定

利用Transition製作切換動畫

前言        使用Transition動畫框架,可以幫你做到:     1不同Activity切換的時候,根據每個activity對應的layout內容的不同做整體的場景變換的動畫。      2 不同activity切換的時候,不同activity對應的lay

Android Studio之Activity切換動畫(三)

文章 oid out size ref intel tar studio anim 1、上一篇文章“Android Studio之多個Activity的滑動切換(二)”中實現了多個activity之間的滑動切換,可是新切換出的activity大多是從右側進入 2、我們能

Android 4.0 Launcher2源碼分析——啟動過程分析

handler flag 這一 第一次啟動 asynctask pla size ontouch wait Android的應用程序的入口定義在AndroidManifest.xml文件中可以找出:[html] <manifest xmlns:android="htt

BUGandroid.content.res.Resources$NotFoundException: File res/drawable-xxhdpi/toolbar_line.png from

設備 cati des dpi com rgs inflater from argument SafeGod在coolpad(4.0)上執行。登陸進去的設備列表界面遇到的問題。三星和索尼沒有這個問題。 06-24 15:23:06.897: E/AndroidRun

Cocos2d-x v3.0正式版嘗鮮體驗2 Android平臺移植

生成 ble ack nts 做的 導入 eclipse so文件 腳本 今天沒事又嘗試了下3.0正式版關於Android平臺的移植,把新建的項目移植了下。過程僅用了十分鐘左右,什麽概念?!好吧,事實上我想說,這個版本號真的移植非常輕松啊,只是還沒加上其它東西,只是就眼

Android:No implementation found for native

stat void for boa bte pre shared int jnienv 解決方法: 1.檢查native c code的定義: JNIEXPORT void Java_com_example_something_MyClass_getMyString(JNI

轉載Android Gradle Build Error:Some file crunching failed, see logs for details解決辦法

mage erl 博客 details efault roi 成了 options 文件 錯誤日誌:Error:java.lang.RuntimeException: Some file crunching failed, see logs for details Lo

Android橫豎屏重力自適應

ron ati lan target 設計 根據 use rpo 適應 通常我們的應用只會設計成橫屏或者豎屏,鎖定橫屏或豎屏的方法是在manifest.xml文件中設定屬性android:screenOrientation為"landscape"或"portrait":

Android路由實現

~~ 下載 bin 一個 setup 自己的路 rul 簡單 sync 本文轉自: http://blog.csdn.net/qibin0506/article/details/53373412 前幾個月有幸參加了CSDN組織的MDCC移動開發者大會, 一天下來我最大的收獲

Android開發筆記(序)寫在前面的目錄

animator 進程間通信 scrip cst 調用 receiver 手勢 打包 數據庫基礎 原文:http://blog.csdn.net/aqi00/article/details/50012511 知識點分類 一方面寫寫自己走過的彎路掉進去的坑,避免以後

Android Camera 相機開發詳解

exc troy start 當前 container rac google getconf 對比度 在Android 5.0(SDK 21)中,Google使用Camera2替代了Camera接口。Camera2在接口和架構上做了巨大的變動, 但是基於眾所周知的原因

Android Studio打包全攻略---從入門到精通

UC store 類型 安裝文件 public alt url tool 描述 原文地址:http://blog.csdn.net/zivensonice/article/details/51672846 初出茅廬 手動打包 怎麽手動打包 項目寫完了,現在需要把應用上傳