Android 圖形和動畫Android Graphics and Animation

Android 提供非常豐富且多樣化的架構,可支援2D 圖形和動畫。本主題將介紹這些架構,並討論如何建立自訂的圖形和動畫,以用於 Xamarin. Android 應用程式。Android provides a very rich and diverse framework for supporting 2D graphics and animations. This topic introduces these frameworks and discusses how to create custom graphics and animations for use in a Xamarin.Android application.

概觀Overview

儘管在傳統上有電力限制的裝置上執行,最高等級的行動應用程式通常會有精密的使用者體驗(UX),並以高品質的圖形和動畫(提供直覺且快速的動態風格)來完成。Despite running on devices that are traditionally of limited power, the highest rated mobile applications often have a sophisticated User Experience (UX), complete with high quality graphics and animations that provide an intuitive, responsive, dynamic feel. 隨著行動應用程式變得更複雜,使用者也開始期待應用程式的越來越多。As mobile applications get more and more sophisticated, users have begun to expect more and more from applications.

幸運的是,現代化的行動平臺具有非常強大的架構,可建立精密的動畫和自訂圖形,同時保有方便使用。Luckily for us, modern mobile platforms have very powerful frameworks for creating sophisticated animations and custom graphics while retaining ease of use. 這可讓開發人員輕鬆地加入豐富的互動。This enables developers to add rich interactivity with very little effort.

Android 中的 UI API 架構大致可以分成兩個類別:圖形和動畫。UI API frameworks in Android can roughly be split into two categories: Graphics and Animation.

圖形會進一步分割成不同的方法來執行2D 和3D 圖形。Graphics are further split into different approaches for doing 2D and 3D graphics. 3D 圖形可透過多個內建的架構(例如 OpenGL ES)和協力廠商架構(例如,MonoGame (與同型工具組相容的跨平臺工具組)來取得。3D graphics are available via a number of built in frameworks such as OpenGL ES (a mobile specific version of OpenGL), and third-party frameworks such as MonoGame (a cross platform toolkit compatible with the XNA toolkit). 雖然3D 圖形不在本文的討論範圍內,但我們將會探討內建的2D 繪圖技術。Although 3D graphics are not within the scope of this article, we will examine the built-in 2D drawing techniques.

Android 提供兩個不同的 API 來建立2D 圖形。Android provides two different API's for creating 2D graphics. 其中一個是高階宣告式方法,另一個是程式設計低層級 API:One is a high level declarative approach and the other a programmatic low-level API:

  • 繪製的資源– 這些是用來以程式設計方式建立自訂圖形,或藉由在 XML 檔案中內嵌繪製指令,以進行更常見的選擇Drawable Resources – These are used to create custom graphics either programmatically or (more typically) by embedding drawing instructions in XML files. 可繪製的資源通常會定義為 XML 檔案,其中包含 Android 呈現2D 圖形的指示或動作。Drawable resources are typically defined as XML files that contain instructions or actions for Android to render a 2D graphic.

  • 畫布– 這是一個低層級的 API,其中牽涉到直接在基礎點陣圖上繪製。Canvas – this is a low level API that involves drawing directly on an underlying bitmap. 它可以對顯示的內容提供非常細微的控制。It provides very fine-grained control over what is displayed.

除了這些2D 圖形技術,Android 也提供數種不同的方式來建立動畫:In addition to these 2D graphics techniques, Android also provides several different ways to create animations:

  • – Android 的可繪製動畫也支援以框架為依據的動畫,稱為「可繪製動畫」。Drawable Animations – Android also supports frame-by-frame animations known as Drawable Animation. 這是最簡單的動畫 API。This is the simplest animation API. Android 會依序載入和顯示依序排列的繪製資源(非常類似于卡通)。Android sequentially loads and displays Drawable resources in sequence (much like a cartoon).

  • 觀看 動畫 – 視圖動畫是android 中的原始動畫 API,並可在所有版本的 android 中使用。View AnimationsView Animations are the original animation API's in Android and are available in all versions of Android. 這個 API 的限制在於,它只會使用 View 物件,而且只能對那些視圖執行簡單的轉換。This API is limited in that it will only work with View objects and can only perform simple transformations on those Views. 視圖動畫通常會定義在 [/Resources/anim] 資料夾中找到的 XML 檔案中。View animations are typically defined in XML files found in the /Resources/anim folder.

  • – Android 3.0 的屬性動畫引進了一組新的動畫 API,稱為屬性動畫Property Animations – Android 3.0 introduced a new set of animation API's known as Property Animations. 這些新的 API 引進了可擴充且彈性的系統,可用來以動畫顯示任何物件的屬性,而不只是 View 物件。These new API's introduced an extensible and flexible system that can be used to animate the properties of any object, not just View objects. 這種彈性可讓動畫封裝在不同的類別中,使程式碼共用變得更容易。This flexibility allows animations to be encapsulated in distinct classes that will make code sharing easier.

視圖動畫更適合必須支援舊版 Android 3.0 API 的應用程式(API 層級11)。View Animations are more suitable for applications that must support the older pre-Android 3.0 API's (API level 11). 否則,應用程式應該使用較新的屬性動畫 API,原因如下所述。Otherwise applications should use the newer Property Animation API's for the reasons that were mentioned above.

所有這些架構都是可行的選項,但在可能的情況下,應該將喜好設定提供給屬性動畫,因為這是更有彈性的 API 可供使用。All of these frameworks are viable options, however where possible, preference should be given to Property Animations, as it is a more flexible API to work with. 屬性動畫允許將動畫邏輯封裝在不同的類別中,使程式碼共用變得更容易,並簡化程式碼維護。Property Animations allow for animation logic to be encapsulated in distinct classes that makes code sharing easier and simplifies code maintenance.

協助工具Accessibility

圖形和動畫有助於讓 Android 應用程式更具吸引力且更有趣的使用;不過,請務必記住,某些互動會透過螢幕助讀程式、替代輸入裝置或輔助縮放來進行。Graphics and animations help to make Android apps attractive and fun to use; however, it is important to remember that some interactions occur via screenreaders, alternate input devices, or with assisted zoom. 此外,某些互動可能會在沒有音訊功能的情況下發生。Also, some interactions may occur without audio capabilities.

在這些情況下,如果應用程式已設計為具有協助工具,就更能使用:在使用者介面中提供提示和導覽協助,並確保 UI 的圖形元素有文字內容或描述。Apps are more usable in these situations if they have been designed with accessibility in mind: providing hints and navigation assistance in the user-interface, and ensuring there is text-content or descriptions for pictorial elements of the UI.

如需如何使用 Android 協助工具 Api 的詳細資訊,請參閱Google 的協助工具指南Refer to Google's Accessibility Guide for more information on how to utilize Android's accessibility APIs.

2D 圖形2D Graphics

可繪製資源是 Android 應用程式中常用的技術。Drawable Resources are a popular technique in Android applications. 如同其他資源,可繪製的資源是在 XML 檔案中定義的宣告式 –。As with other resources, Drawable Resources are declarative – they're defined in XML files. 這種方法可讓您清楚區分程式碼與資源。This approach allows for a clean separation of code from resources. 這可以簡化開發和維護,因為不需要變更程式碼來更新或變更 Android 應用程式中的圖形。This can simplify development and maintenance because it is not necessary to change code to update or change the graphics in an Android application. 不過,雖然可繪製資源適用于許多簡單和一般的圖形需求,但它們缺乏畫布 API 的強大功能和控制權。However, while Drawable Resources are useful for many simple and common graphic requirements, they lack the power and control of the Canvas API.

另一種使用Canvas物件的技巧,非常類似于其他傳統 API 架構,例如 System. 繪圖或 IOS 的核心繪圖。The other technique, using the Canvas object, is very similar to other traditional API frameworks such as System.Drawing or iOS's Core Drawing. 使用 Canvas 物件可讓您充分掌控2D 圖形的建立方式。Using the Canvas object provides the most control of how 2D graphics are created. 這適用于可繪製資源無法使用或很難以處理的情況。It is appropriate for situations where a Drawable Resource will not work or will be difficult to work with. 例如,您可能必須繪製自訂滑杆控制項,其外觀會根據與滑杆值相關的計算而變更。For example, it may be necessary to draw a custom slider control whose appearance will change based on calculations related to the value of the slider.

讓我們先檢查可繪製的資源。Let's examine Drawable Resources first. 它們比較簡單,並涵蓋最常見的自訂繪圖案例。They are simpler and cover the most common custom drawing cases.

繪製資源Drawable Resources

可繪製資源會在目錄 /Resources/drawable的 XML 檔案中定義。Drawable Resources are defined in an XML file in the directory /Resources/drawable. 與內嵌 PNG 或 JPEG 不同的是,不需要提供可繪製資源的密度特定版本。Unlike embedding PNG or JPEG's, it is not necessary to provide density-specific versions of Drawable Resources. 在執行時間,Android 應用程式會載入這些資源,並使用這些 XML 檔案中包含的指示來建立2D 圖形。At runtime, an Android application will load these resources and use the instructions contained in these XML files to create 2D graphics. Android 定義數種不同類型的繪製資源:Android defines several different types of Drawable Resources:

  • ShapeDrawable – 這是可繪製基本幾何形狀並對該圖形套用一組有限圖形效果的可繪製物件。ShapeDrawable – This is a Drawable object that draws a primitive geometric shape and applies a limited set of graphical effects on that shape. 它們非常適合用於自訂按鈕或設定 Textview 的背景等專案。They are very useful for things such as customizing Buttons or setting the background of TextViews. 我們會在本文稍後看到如何使用 ShapeDrawable 的範例。We will see an example of how to use a ShapeDrawable later in this article.

  • StateListDrawable – 這是可繪製的資源,會根據 widget/控制項的狀態變更外觀。StateListDrawable – This is a Drawable Resource that will change appearance based on the state of a widget/control. 例如,按鈕可能會根據是否按下而變更其外觀。For example, a button may change its appearance depending on whether it is pressed or not.

  • LayerDrawable – 此可繪製資源,這會將多個其他可繪製資源堆疊在另一個上。LayerDrawable – This Drawable Resource that will stack several other drawables one on top of another. LayerDrawable的範例如下列螢幕擷取畫面所示:An example of a LayerDrawable is shown in the following screenshot:

    LayerDrawable 範例

  • TransitionDrawable – 這是LayerDrawable ,但有一項差異。TransitionDrawable – This is a LayerDrawable but with one difference. TransitionDrawable能夠以動畫顯示在另一個圖層上方。A TransitionDrawable is able to animate one layer showing up over top another.

  • LevelListDrawable – 這非常類似StateListDrawable ,因為它會根據特定條件來顯示影像。LevelListDrawable – This is very similar to a StateListDrawable in that it will display an image based on certain conditions. 不過,不同于StateListDrawableLevelListDrawable會根據整數值來顯示影像。However, unlike a StateListDrawable, the LevelListDrawable displays an image based on an integer value. LevelListDrawable的範例是顯示 WiFi 信號的強度。An example of a LevelListDrawable would be to display the strength of a WiFi signal. 當 WiFi 信號的強度變更時,顯示的可繪製會隨之改變。As the strength of the WiFi signal changes, the drawable that is displayed will change accordingly.

  • ScaleDrawable / ClipDrawable正–如其名, 這些可繪製資源同時提供縮放和裁剪功能。ScaleDrawable/ClipDrawable – As their name implies, these Drawables provide both scaling and clipping functionality. ScaleDrawable會調整另一個可繪製的,而ClipDrawable會裁剪另一個可繪製的。The ScaleDrawable will scale another Drawable, while the ClipDrawable will clip another Drawable.

  • InsetDrawable – 此可繪製會將內凹套用至另一個可繪製資源的側邊。InsetDrawable – This Drawable will apply insets on the sides of another Drawable resource. 當視圖需要的背景小於此視圖的實際界限時,就會使用它。It is used when a View needs a background that is smaller than the View's actual bounds.

  • XML BitmapDrawable – 此檔案是在實際點陣圖上執行的一組指令,以 xml 表示。XML BitmapDrawable – This file is a set of instructions, in XML, that are to be performed on an actual bitmap. Android 可執行檔某些動作包括並排、抖動和消除鋸齒。Some actions that Android can perform are tiling, dithering, and anti-aliasing. 其中一個非常常見的用法是在版面配置的背景並排顯示點陣圖。One of the very common uses of this is to tile a bitmap across the background of a layout.

繪製範例Drawable Example

讓我們看一下如何使用 ShapeDrawable建立2D 圖形的快速範例。Let's look at a quick example of how to create a 2D graphic using a ShapeDrawable. ShapeDrawable 可以定義四種基本圖形的其中一個:矩形、橢圓形、線條和環形。A ShapeDrawable can define one of the four basic shapes: rectangle, oval, line, and ring. 也可以套用基本效果,例如漸層、色彩和大小。It is also possible to apply basic effects, such as gradient, colour, and size. 下列 XML 是可以在AnimationsDemo附屬專案(在檔案 Resources/drawable/shape_rounded_blue_rect.xml中)中找到的 ShapeDrawableThe following XML is a ShapeDrawable that may be found in the AnimationsDemo companion project (in the file Resources/drawable/shape_rounded_blue_rect.xml). 它會定義具有紫色漸層背景和圓角的矩形:It defines a rectangle with a purple gradient background and rounded corners:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<!-- Specify a gradient for the background -->
<gradient android:angle="45"
          android:startColor="#55000066"
          android:centerColor="#00000000"
          android:endColor="#00000000"
          android:centerX="0.75" />

<padding android:left="5dp"
          android:right="5dp"
          android:top="5dp"
          android:bottom="5dp" />

<corners android:topLeftRadius="10dp"
          android:topRightRadius="10dp"
          android:bottomLeftRadius="10dp"
          android:bottomRightRadius="10dp" />
</shape>

我們可以在版面配置或其他繪製中以宣告方式參考此可繪製資源,如下列 XML 所示:We can reference this Drawable Resource declaratively in a Layout or other Drawable as shown in the following XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#33000000">
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_centerInParent="true"
              android:background="@drawable/shape_rounded_blue_rect"
              android:text="@string/message_shapedrawable" />
</RelativeLayout>

可繪製的資源也可以透過程式設計方式套用。Drawable Resources can also be applied programmatically. 下列程式碼片段顯示如何以程式設計方式設定 TextView 的背景:The following code snippet shows how to programmatically set the background of a TextView:

TextView tv = FindViewById<TextView>(Resource.Id.shapeDrawableTextView);
tv.SetBackgroundResource(Resource.Drawable.shape_rounded_blue_rect);

若要查看這看起來的樣子,請執行AnimationsDemo專案,然後從主功能表中選取 [圖形可繪製] 專案。To see what this would look like, run the AnimationsDemo project and select the Shape Drawable item from the main menu. 我們應該會看到類似下列螢幕擷取畫面的內容:We should see something similar to the following screenshot:

具有自訂背景的 Textview,並以漸層和圓角繪製Textview with a custom background, drawable with a gradient and rounded corners

如需有關可繪製資源的 XML 元素和語法的詳細資訊,請參閱Google 的檔For more details about the XML elements and syntax of Drawable Resources, consult Google's documentation.

使用畫布繪製 APIUsing the Canvas Drawing API

可繪製資源功能強大,但有其限制。Drawables are powerful but have their limitations. 某些事項可能不可行或非常複雜(例如:將篩選套用至裝置上的相機所拍攝的圖片)。Certain things are either not possible or very complex (for example: applying a filter to a picture that was taken by a camera on the device). 藉由使用可繪製的資源,將會非常難以縮減紅眼。It would be very difficult to apply red-eye reduction by using a Drawable Resource. 取而代之的是,畫布 API 可讓應用程式有非常細微的控制,以選擇性地變更圖片特定部分的色彩。Instead, the Canvas API allows an application to have very fine-grained control to selectively change colors in a specific part of the picture.

通常與畫布搭配使用的一個類別是油漆類別。One class that is commonly used with the Canvas is the Paint class. 這個類別會保存如何繪製的色彩和樣式資訊。This class holds colour and style information about how to draw. 它是用來提供色彩和透明度等專案。It is used to provide things such a color and transparency.

畫布 API 會使用此油漆模式來繪製2d 圖形。The Canvas API uses the painter's model to draw 2D graphics. 作業會在彼此之上的後續層中套用。Operations are applied in successive layers on top of each other. 每項作業都會涵蓋基礎點陣圖的某個區域。Each operation will cover some area of the underlying bitmap. 當區域與先前繪製的區域重迭時,新的繪製會部分或完全遮蔽舊的。When the area overlaps a previously painted area, the new paint will partially or completely obscure the old. 這與其他許多繪圖 Api (例如,System. 繪圖和 iOS 的核心圖形)的使用方式相同。This is the same way that many other drawing APIs such as System.Drawing and iOS's Core Graphics work.

有兩種方式可取得 Canvas 物件。There are two ways to obtain a Canvas object. 第一種方式包括定義點陣圖物件,然後使用它來具現化 Canvas 物件。The first way involves defining a Bitmap object, and then instantiating a Canvas object with it. 例如,下列程式碼片段會建立具有基礎點陣圖的新畫布:For example, the following code snippet creates a new canvas with an underlying bitmap:

Bitmap bitmap = Bitmap.CreateBitmap(100, 100, Bitmap.Config.Argb8888);
Canvas canvas = new Canvas(b);

取得 Canvas 物件的另一種方式是透過提供View基類的OnDraw回呼方法。The other way to obtain a Canvas object is by the OnDraw callback method that is provided the View base class. Android 會在決定視圖需要自行繪製,並傳入 Canvas 物件,以供視圖使用時呼叫此方法。Android calls this method when it decides a View needs to draw itself and passes in a Canvas object for the View to work with.

Canvas 類別會公開方法,以程式設計方式提供繪製指示。The Canvas class exposes methods to programmatically provide the draw instructions. 例如:For example:

  • Canvas.DrawPaint–會以指定的繪製填滿整個畫布的點陣圖。Canvas.DrawPaint – Fills the entire canvas's bitmap with the specified paint.

  • Canvas.DrawPath –使用指定的繪製繪製指定的幾何形狀。Canvas.DrawPath – Draws the specified geometric shape using the specified paint.

  • Canvas.DrawText –會以指定的色彩繪製畫布上的文字。Canvas.DrawText – Draws the text on the canvas with the specified colour. 文字會在位置 x,y 繪製。The text is drawn at location x,y .

使用畫布 API 繪製Drawing with the Canvas API

以下是作用中畫布 API 的範例。Here's an example of the Canvas API in action. 下列程式碼片段顯示如何繪製視圖:The following code snippet shows how to draw a view:

public class MyView : View
{
    protected override void OnDraw(Canvas canvas)
    {
        base.OnDraw(canvas);
        Paint green = new Paint {
            AntiAlias = true,
            Color = Color.Rgb(0x99, 0xcc, 0),
        };
        green.SetStyle(Paint.Style.FillAndStroke);

        Paint red = new Paint {
            AntiAlias = true,
            Color = Color.Rgb(0xff, 0x44, 0x44)
        };
        red.SetStyle(Paint.Style.FillAndStroke);

        float middle = canvas.Width * 0.25f;
        canvas.DrawPaint(red);
        canvas.DrawRect(0, 0, middle, canvas.Height, green);
    }
}

上述程式碼會先建立紅色繪製和綠色繪製物件。This code above first creates a red paint and a green paint object. 它會以紅色填滿畫布的內容,然後指示畫布繪製一個綠色矩形,其為畫布寬度的25%。It fills the content of the canvas with red, and then instructs the canvas to draw a green rectangle that is 25% of the width of the canvas. 如需這項工作的範例,請參閱本文的原始程式碼所包含的 AnimationsDemo 專案。An example of this can be seen by in AnimationsDemo project that is included with the source code for this article. 藉由啟動應用程式,然後從主功能表中選取繪製專案,我們應該會顯示類似下面的畫面:By starting up the application and selecting the Drawing item from the main menu, we should a screen similar to the following:

具有紅色油漆和綠色繪製物件的 畫面Screen with red paint and green paint objects

動畫Animation

使用者喜歡在其應用程式中移動的專案。Users like things that move in their applications. 動畫是改善應用程式使用者體驗並協助它脫穎而出的絕佳方式。最佳動畫是使用者不會注意到的效果,因為他們覺得自然。Animations are a great way to improve the user experience of an application and help it stand out. The best animations are the ones that users don't notice because they feel natural. Android 為動畫提供下列三個 API:Android provides the following three API's for animations:

  • View 動畫– 這是原始 API。View Animation – This is the original API. 這些動畫會系結至特定的視圖,而且可以對視圖內容執行簡單的轉換。These animations are tied to a specific View and can perform simple transformations on the contents of the View. 因為這是簡單的,此 API 仍然適用于 Alpha 動畫、旋轉等專案。Because of it's simplicity, this API still useful for things like alpha animations, rotations, and so forth.

  • 屬性動畫– 在 Android 3.0 中引進屬性動畫。Property Animation – Property animations were introduced in Android 3.0. 它們可讓應用程式建立幾乎任何專案的動畫。They enable an application to animate almost anything. 屬性動畫可以用來變更任何物件的任何屬性,即使該物件在螢幕上看不到也一樣。Property animations can be used to change any property of any object, even if that object is not visible on the screen.

  • 繪製的動畫– 這個特殊的可繪製資源,用來將非常簡單的動畫效果套用至配置。Drawable Animation – This a special Drawable resource that is used to apply a very simple animation effect to layouts.

一般而言,屬性動畫是慣用的系統,因為它較有彈性,並提供更多功能。In general, property animation is the preferred system to use as it is more flexible and offers more features.

視圖動畫View Animations

視圖動畫僅限於視圖,而且只能對起點和終點、大小、旋轉和透明度等值執行動畫。View animations are limited to Views and can only perform animations on values such as start and end points, size, rotation, and transparency. 這些類型的動畫通常稱為「補間動畫」。These types of animations are typically referred to as tween animations. 您可以用程式設計方式或使用 XML 檔案,以兩種方式來定義視圖動畫 –。View animations can be defined two ways – programmatically in code or by using XML files. XML 檔案是宣告視圖動畫的慣用方式,因為它們更容易閱讀且更易於維護。XML files are the preferred way to declare view animations, as they are more readable and easier to maintain.

動畫 XML 檔案會儲存在 Xamarin Android 專案的 /Resources/anim 目錄中。The animation XML files will be stored in the /Resources/anim directory of a Xamarin.Android project. 此檔案必須具有下列其中一個元素做為根項目:This file must have one of the following elements as the root element :

  • alpha – 淡入或淡出動畫。alpha – A fade-in or fade-out animation.

  • rotate – 旋轉動畫。rotate – A rotation animation.

  • scale – 調整大小動畫。scale – A resizing animation.

  • translate – 水準和/或垂直動作。translate – A horizontal and/or vertical motion.

  • set – 可能保留一或多個其他動畫元素的容器。set – A container that may hold one or more of the other animation elements.

根據預設,會同時套用 XML 檔案中的所有動畫。By default, all animations in an XML file will be applied simultaneously. 若要依序執行動畫,請在上面定義的其中一個元素上設定 android:startOffset 屬性。To make animations occur sequentially, set the android:startOffset attribute on one of the elements defined above.

您可以使用轉器來影響動畫中變更的速率。It is possible to affect the rate of change in an animation by using an interpolator. 插即用可以加速、重複或 decelerated 動畫效果。An interpolator makes it possible for animation effects to be accelerated, repeated, or decelerated. Android framework 提供幾個現成可用的 interpolators,例如(但不限於):The Android framework provides several interpolators out of the box, such as (but not limited to):

  • AccelerateInterpolator / DecelerateInterpolator – 這些 interpolators 會增加或減少動畫中的變更率。AccelerateInterpolator / DecelerateInterpolator – these interpolators increase or decrease the rate of change in an animation.

  • BounceInterpolator – 結束時的變更。BounceInterpolator – the change bounces at the end.

  • LinearInterpolator – 變更的速率是固定的。LinearInterpolator – the rate of changes is constant.

下列 XML 顯示結合下列部分元素的動畫檔案範例:The following XML shows an example of an animation file that combines some of these elements:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android=http://schemas.android.com/apk/res/android
     android:shareInterpolator="false">

    <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator"
           android:fromXScale="1.0"
           android:toXScale="1.4"
           android:fromYScale="1.0"
           android:toYScale="0.6"
           android:pivotX="50%"
           android:pivotY="50%"
           android:fillEnabled="true"
           android:fillAfter="false"
           android:duration="700" />

    <set android:interpolator="@android:anim/accelerate_interpolator">
        <scale android:fromXScale="1.4"
               android:toXScale="0.0"
               android:fromYScale="0.6"
               android:toYScale="0.0"
               android:pivotX="50%"
               android:pivotY="50%"
               android:fillEnabled="true"
               android:fillBefore="false"
               android:fillAfter="true"
               android:startOffset="700"
               android:duration="400" />

        <rotate android:fromDegrees="0"
                android:toDegrees="-45"
                android:toYScale="0.0"
                android:pivotX="50%"
                android:pivotY="50%"
                android:fillEnabled="true"
                android:fillBefore="false"
                android:fillAfter="true"
                android:startOffset="700"
                android:duration="400" />
    </set>
</set>

這個動畫會同時執行所有的動畫。This animation will perform all of the animations simultaneously. 第一個尺規動畫會水準延展影像並垂直縮小,然後影像會以順時針和縮小的方式同時旋轉45度(從螢幕中消失)。The first scale animation will stretch the image horizontally and shrink it vertically, and then the image will simultaneously be rotated 45 degrees counter-clockwise and shrink, disappearing from the screen.

動畫可以透過因而誇大動畫,然後套用至視圖,以程式設計方式套用至視圖。The animation can be programmatically applied to a View by inflating the animation and then applying it to a View. Android 提供的 helper 類別 Android.Views.Animations.AnimationUtils 將會擴充動畫資源,並傳回 Android.Views.Animations.Animation的實例。Android provides the helper class Android.Views.Animations.AnimationUtils that will inflate an animation resource and return an instance of Android.Views.Animations.Animation. 這個物件會藉由呼叫 StartAnimation 並傳遞 Animation 物件,套用至視圖。This object is applied to a View by calling StartAnimation and passing the Animation object. 下列程式碼片段顯示這種情況的範例:The following code snippet shows an example of this:

Animation myAnimation = AnimationUtils.LoadAnimation(Resource.Animation.MyAnimation);
ImageView myImage = FindViewById<ImageView>(Resource.Id.imageView1);
myImage.StartAnimation(myAnimation);

既然我們已經對觀看動畫的工作方式有基本瞭解,讓我們移至屬性動畫。Now that we have a fundamental understanding of how View Animations work, lets move to Property Animations.

屬性動畫Property Animations

屬性 animators 是在 Android 3.0 中引進的新 API。Property animators are a new API that was introduced in Android 3.0. 它們提供更可擴充的 API,可以用來建立任何物件上任何屬性的動畫。They provide a more extensible API that can be used to animate any property on any object.

所有屬性動畫都是由Animator子類別的實例所建立。All property animations are created by instances of the Animator subclass. 應用程式不會直接使用此類別,而是使用其中一個子類別:Applications do not directly use this class, instead they use one of it's subclasses:

  • ValueAnimator – 此類別是整個屬性動畫 API 中最重要的類別。ValueAnimator – This class is the most important class in the entire property animation API. 它會計算需要變更之屬性的值。It calculates the values of properties that need to be changed. ViewAnimator 不會直接更新那些值;相反地,它會引發可用於更新動畫物件的事件。The ViewAnimator does not directly update those values; instead, it raises events that can be used to update animated objects.

  • ObjectAnimator – 此類別是 ValueAnimator 的子類別。ObjectAnimator – This class is a subclass of ValueAnimator . 它的目的是要藉由接受目標物件和要更新的屬性,來簡化物件的動畫處理常式。It is meant to simplify the process of animating objects by accepting a target object and property to update.

  • AnimationSet – 這個類別會負責協調動畫的相互關聯方式。AnimationSet – This class is responsible for orchestrating how animations run in relation to one another. 動畫可能會依序執行,或在兩者之間有指定的延遲。Animations may run simultaneously, sequentially, or with a specified delay between them.

評估工具是 animators 在動畫期間用來計算新值的特殊類別。Evaluators are special classes that are used by animators to calculate the new values during an animation. Android 提供下列評估工具:Out of the box, Android provides the following evaluators:

如果要繪製動畫的屬性不是 floatint 或色彩,應用程式可以藉由執行 ITypeEvaluator 介面來建立自己的評估工具。If the property that is being animated is not a float, int or colour, applications may create their own evaluator by implementing the ITypeEvaluator interface. (執行自訂評估工具已超出本主題的範圍)。(Implementing custom evaluators is beyond the scope of this topic.)

使用 ValueAnimatorUsing the ValueAnimator

任何動畫都有兩個部分:計算動畫值,然後在某個物件的屬性上設定這些值。There are two parts to any animation: calculating animated values and then setting those values on properties on some object. ValueAnimator只會計算值,但不會直接在物件上操作。ValueAnimator will only calculate the values, but it will not operate on objects directly. 相反地,物件將會在動畫存留期間所叫用的事件處理常式內更新。Instead, objects will be updated inside event handlers that will be invoked during the animation lifespan. 此設計可讓您從一個動畫值更新數個屬性。This design allows several properties to be updated from one animated value.

您可以藉由呼叫下列其中一個 factory 方法來取得 ValueAnimator 的實例:You obtain an instance of ValueAnimator by calling one of the following factory methods:

  • ValueAnimator.OfInt
  • ValueAnimator.OfFloat
  • ValueAnimator.OfObject

完成後,ValueAnimator 實例必須設定其持續時間,然後可以啟動。Once that is done, the ValueAnimator instance must have its duration set, and then it can be started. 下列範例示範如何在1000毫秒的範圍內,以動畫顯示0到1之間的值:The following example shows how to animate a value from 0 to 1 over the span of 1000 milliseconds:

ValueAnimator animator = ValueAnimator.OfInt(0, 100);
animator.SetDuration(1000);
animator.Start();

但是,上述程式碼片段本身並不太實用 – animator 將會執行,但是更新的值沒有目標。But itself, the code snippet above is not very useful – the animator will run but there is no target for the updated value. Animator 類別決定必須通知新值的接聽程式時,就會引發 Update 事件。The Animator class will raise the Update event when it decides that it is necessary to inform listeners of a new value. 應用程式可以提供事件處理常式來回應此事件,如下列程式碼片段所示:Applications may provide an event handler to respond to this event as shown in the following code snippet:

MyCustomObject myObj = new MyCustomObject();
myObj.SomeIntegerValue = -1;

animator.Update += (object sender, ValueAnimator.AnimatorUpdateEventArgs e) =>
{
    int newValue = (int) e.Animation.AnimatedValue;
    // Apply this new value to the object being animated.
    myObj.SomeIntegerValue = newValue;
};

既然我們已經瞭解 ValueAnimator,讓我們深入瞭解 ObjectAnimatorNow that we have an understanding of ValueAnimator, lets learn more about the ObjectAnimator.

使用 ObjectAnimatorUsing the ObjectAnimator

ObjectAnimatorViewAnimator 的子類別,可結合 ValueAnimator 的計時引擎和值計算與連接事件處理常式所需的邏輯。ObjectAnimator is a subclass of ViewAnimator that combines the timing engine and value computation of the ValueAnimator with the logic required to wire up event handlers. ValueAnimator 需要應用程式明確地連接事件處理常式 – ObjectAnimator 會為我們處理此步驟。The ValueAnimator requires applications to explicitly wire up an event handler – ObjectAnimator will take care of this step for us.

ObjectAnimator 的 API 與適用于 ViewAnimator的 API 非常類似,但您需要提供物件和要更新的屬性名稱。The API for ObjectAnimator is very similar to the API for ViewAnimator, but requires that you provide the object and the name of the property to update. 下列範例顯示使用 ObjectAnimator的範例:The following example shows an example of using ObjectAnimator:

MyCustomObject myObj = new MyCustomObject();
myObj.SomeIntegerValue = -1;

ObjectAnimator animator = ObjectAnimator.OfFloat(myObj, "SomeIntegerValue", 0, 100);
animator.SetDuration(1000);
animator.Start();

如您在先前的程式碼片段中所見,ObjectAnimator 可以減少和簡化以動畫顯示物件所需的程式碼。As you can see from the previous code snippet, ObjectAnimator can reduce and simplify the code that is necessary to animate an object.

繪製動畫Drawable Animations

最後的動畫 API 是可繪製的動畫 API。The final animation API is the Drawable Animation API. 可繪製的動畫會逐一載入一系列的可繪製資源,並依序顯示它們,類似于「翻轉-it」卡通。Drawable animations load a series of Drawable resources one after the other and display them sequentially, similar to a flip-it cartoon.

可繪製資源是在 XML 檔案中定義,該檔案具有做為根項目的 <animation-list> 專案,以及定義動畫中每個框架的一系列 <item> 元素。Drawable resources are defined in an XML file that has an <animation-list> element as the root element and a series of <item> elements that define each frame in the animation. 這個 XML 檔案會儲存在應用程式的 [/Resource/drawable] 資料夾中。This XML file is stored in the /Resource/drawable folder of the application. 下列 XML 是可繪製動畫的範例:The following XML is an example of a drawable animation:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@drawable/asteroid01" android:duration="100" />
  <item android:drawable="@drawable/asteroid02" android:duration="100" />
  <item android:drawable="@drawable/asteroid03" android:duration="100" />
  <item android:drawable="@drawable/asteroid04" android:duration="100" />
  <item android:drawable="@drawable/asteroid05" android:duration="100" />
  <item android:drawable="@drawable/asteroid06" android:duration="100" />
</animation-list>

這個動畫將會執行六個畫面格。This animation will run through six frames. android:duration 屬性會宣告每個畫面格的顯示時間長度。The android:duration attribute declares how long each frame will be displayed. 下一個程式碼片段顯示一個範例,示範如何建立可繪製的動畫,並在使用者按一下螢幕上的按鈕時啟動它:The next code snippet shows an example of creating a Drawable animation and starting it when the user clicks a button on the screen:

AnimationDrawable _asteroidDrawable;

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    SetContentView(Resource.Layout.Main);

    _asteroidDrawable = (Android.Graphics.Drawables.AnimationDrawable)
    Resources.GetDrawable(Resource.Drawable.spinning_asteroid);

    ImageView asteroidImage = FindViewById<ImageView>(Resource.Id.imageView2);
    asteroidImage.SetImageDrawable((Android.Graphics.Drawables.Drawable) _asteroidDrawable);

    Button asteroidButton = FindViewById<Button>(Resource.Id.spinAsteroid);
    asteroidButton.Click += (sender, e) =>
    {
        _asteroidDrawable.Start();
    };
}

此時,我們已涵蓋 Android 應用程式中可用動畫 Api 的基礎。At this point we have covered the foundations of the animation APIs available in an Android application.

總結Summary

本文引進了許多新概念和 API,以協助將一些圖形新增至 Android 應用程式。This article introduced a lot of new concepts and API's to help add some graphics to an Android application. 首先,它討論了各種2D 圖形 API,並示範了 Android 如何讓應用程式使用 Canvas 物件直接繪製到螢幕上。First it discussed the various 2D graphics API's and demonstrated how Android allows applications to draw directly to the screen using a Canvas object. 我們也看到一些替代的技術,可讓您使用 XML 檔案以宣告方式建立圖形。We also saw some alternate techniques that allow graphics to be declaratively created using XML files. 然後我們會討論如何在 Android 中建立動畫的新舊 API。Then we went on to discuss the old and new API's for creating animations in Android.