Skip to content

Most visited

Recently visited

navigation

定義自訂動畫

材料設計中的動畫讓使用者在進行操作動作之後獲得回饋,並且在使用者與您的應用程式互動時提供視覺上的連續性。 材料設計風格針對按鈕和操作行為轉換,提供某些預設的動畫,而 Android 5.0 (API 級別 21) 以上版本則可讓您自訂這些動畫並建立新的動畫:

自訂輕觸回饋

當使用者與 UI 元素互動時,材料設計中的輕觸回饋在接觸點提供即時的視覺化確認。 按鈕的預設輕觸回饋動畫使用新的 RippleDrawable 類別,透過漣漪效果在不同狀態之間進行轉換。

大多數情況下,您應該在視圖 XML 中將視圖背景指定為下列項目以套用此功能:

注意:selectableItemBackgroundBorderless 是 API 級別 21 推出的新屬性。

或者,您也可以使用 ripple 元素將 RippleDrawable 定義為 XML 資源。

您可以對 RippleDrawable 物件指定色彩。如要變更預設的輕觸回饋色彩,請使用設計風格的 android:colorControlHighlight 屬性。

如需詳細資訊,請參閱 RippleDrawable 類別的 API 參考資料。

使用顯示效果

當您顯示或隱藏一組 UI 元素時,顯示動畫可提供使用者視覺上的連續性。 ViewAnimationUtils.createCircularReveal()方法可讓您以動畫顯示裁剪的圓形,以顯示或隱藏視圖。

使用下列效果顯示之前看不見的視圖:

// previously invisible view
View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;

// get the final radius for the clipping circle
int finalRadius = Math.max(myView.getWidth(), myView.getHeight());

// create the animator for this view (the start radius is zero)
Animator anim =
    ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);

// make the view visible and start the animation
myView.setVisibility(View.VISIBLE);
anim.start();

使用下列效果隱藏之前看見的視圖:

// previously visible view
final View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;

// get the initial radius for the clipping circle
int initialRadius = myView.getWidth();

// create the animation (the final radius is zero)
Animator anim =
    ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);

// make the view invisible when the animation is done
anim.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        myView.setVisibility(View.INVISIBLE);
    }
});

// start the animation
anim.start();

自訂操作行為轉換

圖 1 - 使用分享元素的轉換。

如要重播影片,請按一下裝置螢幕

材料設計應用程式中的操作行為轉換透過常見元素之間的動作和轉換,在不同的狀態之間提供視覺上的連接效果。 您可針對進入和離開轉換及不同操作行為之間分享元素的轉換指定自訂動畫。

Android 5.0 (API 級別 21) 支援下列進入和離開轉換:

所有延伸 Visibility 類別的轉換都可作為進入或離開轉換。 如需詳細資訊,請參閱 Transition 類別的 API 參考資料。

Android 5.0 (API 級別 21) 也支援下列分享元素轉換:

當您在應用程式中啟用操作行為轉換時,進入和離開操作行為之間會啟動預設交錯淡化轉換。

  圖 2 - 使用一個分享元素的場景轉換。

指定自訂轉換

首先,當您定義一個從材料設計風格繼承而來的樣式時,請使用 android:windowContentTransitions 屬性啟用視窗內容轉換。 您也可在樣式定義中指定進入、離開和分享元素轉換:

<style name="BaseAppTheme" parent="android:Theme.Material">
  <!-- enable window content transitions -->
  <item name="android:windowContentTransitions">true</item>

  <!-- specify enter and exit transitions -->
  <item name="android:windowEnterTransition">@transition/explode</item>
  <item name="android:windowExitTransition">@transition/explode</item>

  <!-- specify shared element transitions -->
  <item name="android:windowSharedElementEnterTransition">
    @transition/change_image_transform</item>
  <item name="android:windowSharedElementExitTransition">
    @transition/change_image_transform</item>
</style>

此範例中的 change_image_transform 轉換定義如下:

<!-- res/transition/change_image_transform.xml -->
<!-- (see also Shared Transitions below) -->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
  <changeImageTransform/>
</transitionSet>

changeImageTransform 元素對應至 ChangeImageTransform 類別。 如需詳細資訊,請參閱 Transition 的 API 參考資料。

如要在程式碼中改為啟用視窗內容轉換,請呼叫 Window.requestFeature()方法:

// inside your activity (if you did not enable transitions in your theme)
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

// set an exit transition
getWindow().setExitTransition(new Explode());

如要在程式碼中指定轉換,請以 Transition 物件呼叫下列方法:

setExitTransition()setSharedElementExitTransition() 方法定義了呼叫操作行為的離開轉換。 setEnterTransition()setSharedElementEnterTransition() 方法定義被呼叫操作行為的進入轉換。

如要取得轉換的完整效果,您必須同時對呼叫與被呼叫操作行為啟用視窗內容轉換。 否則,呼叫操作行為會啟動離開轉換,然後您只會看到視窗轉換 (類似調整大小或淡化)。

如要立即啟動進入轉換,請對被呼叫的操作行為使用 Window.setAllowEnterTransitionOverlap() 方法。 這樣您就會有更戲劇性的進入轉換。

使用轉換啟動操作行為

若您啟用轉換並對操作行為設定離開轉換,當您啟動另一個操作行為時,就會啟動轉換,如下所示:

startActivity(intent,
              ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

若您已針對第二個操作行為設定進入轉換,當操作行為啟動時,也會啟動轉換。 若要在啟動另一個操作行為時停用轉換,請提供 null 選項組合。

使用一個分享元素啟動操作行為

在兩個擁有分享元素的操作行為之間製作螢幕轉換動畫:

  1. 在設計風格中啟用視窗內容轉換。
  2. 在樣式中指定分享元素轉換。
  3. 將您的轉換定義為 XML 資源。
  4. 使用 android:transitionName 屬性,對兩個版面配置中的分享元素指定通用名稱。
  5. 使用 ActivityOptions.makeSceneTransitionAnimation() 方法。
// get the element that receives the click event
final View imgContainerView = findViewById(R.id.img_container);

// get the common element for the transition in this activity
final View androidRobotView = findViewById(R.id.image_small);

// define a click listener
imgContainerView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(this, Activity2.class);
        // create the transition animation - the images in the layouts
        // of both activities are defined with android:transitionName="robot"
        ActivityOptions options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot");
        // start the new activity
        startActivity(intent, options.toBundle());
    }
});

對於您在程式碼中所產生的分享動態視圖,請使用 View.setTransitionName() 方法,在兩個操作行為中指定通用元素名稱。

如要在完成第二個操作行為時倒轉場景轉換動畫,請呼叫 Activity.finishAfterTransition() 方法而不是 Activity.finish()

使用多個分享元素啟動操作行為

如要在兩個具有多個分享元素的操作行為之間製作場景轉換動畫,請使用 android:transitionName 屬性在兩個版面配置中定義分享元素 (或在兩個操作行為中使用 View.setTransitionName() 方法),然後建立 ActivityOptions 物件,如下所示:

ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
        Pair.create(view1, "agreedName1"),
        Pair.create(view2, "agreedName2"));

使用曲線動作

材料設計中的動畫依據使用時間插值法和空間移動模式的曲線而定。 在 Android 5.0 (API 級別 21) 及以上版本中,您可為動畫定義自訂時間曲線和曲線動作模式。

PathInterpolator 類別是根據貝茲曲線 (Bézier curve) 或 Path 物件的一種新插值器。 這個插值器在一個 1x1 的方格中指定動作曲線,在 (0,0) 和 (1,1) 有兩個錨定點,以及使用建構函式引數指定的控制點。 您也可以將路徑插值器定義為 XML 資源:

<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:controlX1="0.4"
    android:controlY1="0"
    android:controlX2="1"
    android:controlY2="1"/>

系統在材料設計規格中提供三種基本曲線的 XML 資源:

您可將 PathInterpolator 物件傳送至 Animator.setInterpolator() 方法。

ObjectAnimator 類別有新的建構函式,可讓您一次使用兩個以上的屬性沿著路徑以動畫顯示座標。 例如,下列動畫器使用 Path 物件,以動畫顯示視圖的 X 和 Y 屬性:

ObjectAnimator mAnimator;
mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
...
mAnimator.start();

動畫顯示視圖狀態變更

StateListAnimator 類別可讓您定義視圖狀態變更時所執行的動畫器。 下列範例示範如何將 StateListAnimator 定義為 XML 資源:

<!-- animate the translationZ property of a view when pressed -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true">
    <set>
      <objectAnimator android:propertyName="translationZ"
        android:duration="@android:integer/config_shortAnimTime"
        android:valueTo="2dp"
        android:valueType="floatType"/>
        <!-- you could have other objectAnimator elements
             here for "x" and "y", or other properties -->
    </set>
  </item>
  <item android:state_enabled="true"
    android:state_pressed="false"
    android:state_focused="true">
    <set>
      <objectAnimator android:propertyName="translationZ"
        android:duration="100"
        android:valueTo="0"
        android:valueType="floatType"/>
    </set>
  </item>
</selector>

如要將自訂的視圖狀態動畫連接到視圖,請依照此範例在 XML 資源檔案中使用 selector 元素定義動畫器,並使用 android:stateListAnimator 屬性將其指派到您的視圖。 如要在程式碼中為視圖指派狀態清單動畫器,請使用 AnimationInflater.loadStateListAnimator() 方法,然後使用 View.setStateListAnimator() 方法將動畫器指派到您的視圖。

當您的設計風格延伸材料設計風格時,按鈕預設會有 Z 動畫。如果要避免在按鈕中出現這類行為,請將 android:stateListAnimator 屬性設定為 @null

AnimatedStateListDrawable 類別可讓您在相關視圖的狀態變更之間,建立顯示動畫的可繪項目。 Android 5.0 中的某些系統小工具預設會使用這些動畫。 下列範例示範如何將 AnimatedStateListDrawable 定義為 XML 資源:

<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- provide a different drawable for each state-->
    <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
        android:state_pressed="true"/>
    <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
        android:state_focused="true"/>
    <item android:id="@id/default"
        android:drawable="@drawable/drawableD"/>

    <!-- specify a transition -->
    <transition android:fromId="@+id/default" android:toId="@+id/pressed">
        <animation-list>
            <item android:duration="15" android:drawable="@drawable/dt1"/>
            <item android:duration="15" android:drawable="@drawable/dt2"/>
            ...
        </animation-list>
    </transition>
    ...
</animated-selector>

動畫顯示矢量可繪

矢量可繪可以調整大小,但又不會喪失定義。 AnimatedVectorDrawable 類別可讓您以動畫顯示矢量可繪的屬性。

您通常會在下列三個 XML 檔案中定義能可動矢量可繪:

可動的矢量可繪能以動畫顯示 <group><path> 元素的屬性。 <group> 元素定義一組路徑或子群組,而 <path> 元素則定義要繪製的路徑。

當您定義要可動的矢量可繪時,請使用 android:name 屬性為群組和路徑指派唯一的名稱,以便從您的動畫器定義參考這些群組和路徑。 例如:

<!-- res/drawable/vectordrawable.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600">
    <group
        android:name="rotationGroup"
        android:pivotX="300.0"
        android:pivotY="300.0"
        android:rotation="45.0" >
        <path
            android:name="v"
            android:fillColor="#000000"
            android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
    </group>
</vector>

可動的矢量可繪定義是依照名稱來參考矢量可繪中的群組和路徑:

<!-- res/drawable/animvectordrawable.xml -->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:drawable="@drawable/vectordrawable" >
    <target
        android:name="rotationGroup"
        android:animation="@anim/rotation" />
    <target
        android:name="v"
        android:animation="@anim/path_morph" />
</animated-vector>

動畫定義代表 ObjectAnimatorAnimatorSet 物件。此範例中的第一個動畫器會 360 度旋轉目標群組:

<!-- res/anim/rotation.xml -->
<objectAnimator
    android:duration="6000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />

此範例中的第二個動畫器會將矢量可繪的路徑從一種形狀變成另外一種形狀。 兩個路徑必須相容才能變形:意即兩個路徑必須有相同數量的命令,而每個命令必須有相同數量的參數。

<!-- res/anim/path_morph.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="3000"
        android:propertyName="pathData"
        android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"
        android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"
        android:valueType="pathType" />
</set>

如需詳細資訊,請參閱 AnimatedVectorDrawable 的 API 參考資料。

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

在 WeChat 上追蹤 Google Developers

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience. (Dec 2017 Android Platform & Tools Survey)