Android 動畫-共享元素動畫

一、簡介

首先看下轉(zhuǎn)場共享元素動畫的效果:

轉(zhuǎn)場共享動畫的代碼實現(xiàn):

ActivityOptions options = ActivityOptions              .makeSceneTransitionAnimation(ShareElementActivity.this, imageView, "share_img");
startActivity(new Intent(this, TwoActivity.class), options.toBundle());

代碼很簡單,startActivity 傳了一個 IntentOptions 主要看 ActivityOptions
ActivityOptions 提供了一個兼容包 ActivityOptionsCompat 并且提供了幾個方法:

  1. ActivityOptionsCompat.makeCustomAnimation(Context context, int enterResId, int exitResId)

  2. ActivityOptionsCompat.makeScaleUpAnimation(View source,int startX, int startY, int startWidth, int startHeight)

  3. ActivityOptionsCompat.makeThumbnailScaleUpAnimation(View source,Bitmap thumbnail, int startX, int startY)

  4. ActivityOptionsCompat.makeSceneTransitionAnimation(Activity activity, View sharedElement, String sharedElementName)

  5. ActivityOptionsCompat.makeSceneTransitionAnimation(Activity activity,Pair(View, String>… sharedElements)

1、makeCustomAnimation從參數(shù)中我們可以發(fā)現(xiàn),這個和overridePendingTransition非常類似,確實,在實現(xiàn)效果上和overridePendingTransition也是相同的。

2、makeScaleUpAnimation效果就是不斷放大一個view.

ActivityOptionsCompat compat = ActivityOptionsCompat.makeScaleUpAnimation(view,view.getWidth() / 2, view.getHeight() / 2, 0, 0);

第1個參數(shù)是scale哪個view的大小,第2和3個參數(shù)是以view為基點,從哪開始動畫,這里是該view的中心,4和5參數(shù)是新的activity從多大開始放大。

3、makeThumbnailScaleUpAnimation 和 makeScaleUpAnimation類似。

4、makeSceneTransitionAnimation 就是場景動畫,在這里就體現(xiàn)在兩個activity中的某些view協(xié)同去完成過度動畫。上面的動畫栗子就是用的這種實現(xiàn)的。兩個關(guān)鍵的參數(shù):第二個是要實現(xiàn)共享的view,第三個是為這個共享view定義的name(transitionName):

<ImageView
    android:id="@+id/iv_img"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:transitionName="@string/shareElement_img"/>

當然也可以有兩個或多個共享的View。用法如下:

Pair<View, String> pair1 = new Pair<View, String>(imageView, getString(R.string.shareElement_img));
Pair<View, String> pair2 = new Pair<View, String>(textView, getString(R.string.shareElement_txt));
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, pair1, pair2);
startActivity(new Intent(this, TwoActivity.class),options.toBundle());

注:為了得到一個完整的動畫效果,我們必須在2個Activity(當前的和正要啟動的)的theme上都要設(shè)置android:windowContentTransitions屬性:

<resources>

    <style name="ShareElementAppTheme" parent="AppTheme">
        <item name="android:windowContentTransitions">true</item>
        <item name="android:windowAllowEnterTransitionOverlap">true</item>
        <item name="android:windowAllowReturnTransitionOverlap">true</item>
        <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
        <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
        <item name="android:windowEnterTransition">@android:transition/explode</item>
        <item name="android:windowExitTransition">@android:transition/explode</item>
    </style>

</resources>

第一個item是我們必須要設(shè)置的。接下來的6個是有規(guī)律的,兩兩一說。前兩個:指定進入和退出的動畫可以重疊。中間兩個:指定我們使用sharedElement時的進入和退出動畫。最后兩個:指定普通進入和退出的transition。這里使用的是系統(tǒng)自帶的。不指定效果的話,系統(tǒng)會使用默認效果。

當然我們也能自定義效果,Android 5.0(API 級別 21)也支持這些共享元素轉(zhuǎn)換:

  • changeBounds - 為目標視圖的布局邊界的變化添加動畫。
  • changeClipBounds - 為目標視圖的裁剪邊界的變化添加動畫。
  • changeTransform - 為目標視圖的縮放與旋轉(zhuǎn)變化添加動畫。
  • changeImageTransform - 為目標圖像的大小與縮放變化添加動畫。

使用 sharedElement 可以自定義transition:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="500"/>
</transitionSet>

這里我們給changeBounds指定了速度插值器是加速度減速度插值,系統(tǒng)將為 Material Design 規(guī)范中的三種基本曲線提供 XML 資源:

  • @interpolator/fast_out_linear_in.xml
  • @interpolator/fast_out_slow_in.xml
  • @interpolator/linear_out_slow_in.xml

二、結(jié)語

轉(zhuǎn)場共享元素動畫的實現(xiàn)基本就是這樣。簡單的栗子代碼詳見GitHub。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容