適用於 Windows 應用程式的連接動畫

連接動畫可讓兩個不同檢視之間元素的轉換有動畫效果,而產生動態且迷人的瀏覽體驗。 這有助於使用者維護其內容,並提供檢視之間的持續性。

在連接動畫中,UI 內容變更期間,元素似乎在兩個檢視之間「繼續存在」,從來源檢視中的位置飛過畫面到新檢視中的目的地。 這會強調檢視之間的共同內容,並在轉換時建立美觀且動態的效果。

重要 APIConnectedAnimation 類別ConnectedAnimationService 類別

範例

WinUI 2 Gallery
WinUI Gallery

如果您已安裝 WinUI 2 資源庫應用程式,請按一下此處以開啟應用程式並查看連接動畫的運作情形

在此短片中,應用程式會使用連接動畫來建立項目影像的動畫,因為它會「繼續」成為次頁標題的一部分。 效果有助於在整個轉換中維持使用者內容。

Connected Animation

連接動畫和 Fluent Design 系統

Fluent Design 系統能協助您建立結合光線、深度、動作、材質及縮放比例的現代化前衛 UI。 連接動畫是 Fluent Design 系統元件,可將動作新增至您的應用程式。 若要深入了解,請參閱 Fluent Design 概觀

為何使用連接動畫?

在頁面之間瀏覽時,使用者必須要瞭解瀏覽之後呈現哪些新內容,以及這些內容與他們的瀏覽意圖有何關係。 連接動畫提供強大的視覺隱喻,透過將使用者的注意力吸引到兩個檢視之間共享的內容來強調兩個檢視之間的關係。 此外,連接動畫可以增加頁面瀏覽的視覺趣味和美感,有助於區分應用程式的動作設計。

使用連接動畫的時機

連接動畫通常在變更頁面時使用,但它們可以套用於在 UI 中變更內容並希望使用者維護內容的任何體驗。 只要來源檢視和目標檢視之間共用影像或其他 UI 部分,您就應該考慮在瀏覽轉換中使用連接動畫而不是鑽取。

設定連接動畫

重要

此功能要求您應用程式的目標版本為 Windows 10 版本 1809 (SDK 17763) 或更新版本。 舊版 SDK 中無法使用 Configuration 屬性。 您可以使用調適型程式碼或條式 XAML,將低於 SDK 17763 的最低版本作為目標。 如需詳細資訊,請參閱版本調適型應用程式

從 Windows 10 版本 1809 開始,連接動畫透過提供專為向前和向後頁面瀏覽量身定制的動畫設定,進一步體現了 Fluent 設計。

您可以透過設定 ConnectedAnimation 的 Configuration 屬性,來指定動畫設定。 (我們將在下一節中示範這方面的範例。)

此表描述了可用的設定。 如需這些動畫中套用動作原則的詳細資訊,請參閱方向性和重力

GravityConnectedAnimationConfiguration
這是預設設定,建議用於向前瀏覽。
當使用者在應用程式中向前瀏覽 (A 到 B) 時,連接的元素看起來就像「脫離頁面」。 這樣做時,該元素似乎在 z 空間中向前移動,並且由於重力作用而稍微下降。 為了克服重力的影響,元件獲得速度並加速到其最終位置。 結果就變成「縮放和下降」動畫。
DirectConnectedAnimationConfiguration
當使用者在應用程式中向後瀏覽 (B 到 A) 時,動畫更加直接。 連接的元素使用減速三次 Bezier 緩動函式從 B 線性平移到 A。 向後的視覺可供性使使用者盡快返回到先前的狀態,同時仍保持瀏覽流程的內容。
BasicConnectedAnimationConfiguration
這是 Windows 10 版本 1809 (SDK 17763) 之前的版本中使用的預設 (也是唯一) 動畫。

ConnectedAnimationService 設定

ConnectedAnimationService 類別有兩個屬性適用於各個動畫而不是整個服務。

為了實現各種效果,某些設定會忽略 ConnectedAnimationService 上的這些屬性並使用它們自己的值,如下表所述。

設定 遵守 DefaultDuration? 遵守 DefaultEasingFunction?
重力 是*
*從 A 到 B 的基本轉換使用此緩動函式,但「重力傾角」有其自己的緩動函式。
直接
動畫超過 150 毫秒。

使用減速緩動函式。
基本

如何實作連接動畫

設定連接動畫涉及兩個步驟:

  1. 在來源頁面上準備一個動畫物件,該物件會向系統指示來源元素將參與連接的動畫。
  2. 在目標頁面上啟動動畫,傳遞對目標元素的參考。

從來源頁面瀏覽時,呼叫 ConnectedAnimationService.GetForCurrentView 以取得 ConnectedAnimationService 的執行個體。 若要準備動畫,請在此執行個體上呼叫 PrepareToAnimate,並傳入唯一索引鍵和要在轉換中使用的 UI 元素。 唯一索引鍵可讓您稍後在目的地頁面上擷取動畫。

ConnectedAnimationService.GetForCurrentView()
    .PrepareToAnimate("forwardAnimation", SourceImage);

發生瀏覽時,在目標頁面中啟動動畫。 若要啟動動畫,請呼叫 ConnectedAnimation.TryStart。 您可以透過使用建立動畫時提供的唯一索引鍵呼叫 ConnectedAnimationService.GetAnimation 來擷取正確的動畫執行個體。

ConnectedAnimation animation =
    ConnectedAnimationService.GetForCurrentView().GetAnimation("forwardAnimation");
if (animation != null)
{
    animation.TryStart(DestinationImage);
}

向前瀏覽

此範例示範如何使用 ConnectedAnimationService 建立兩個頁面 (Page_A 到 Page_B) 之間的向前瀏覽的轉換。

建議的向前瀏覽動畫設定是 GravityConnectedAnimationConfiguration。 這是預設設置,因此不需要設定 Configuration 屬性,除非您想要指定不同的設定。

在來源頁面中設定動畫。

<!-- Page_A.xaml -->

<Image x:Name="SourceImage"
       HorizontalAlignment="Left" VerticalAlignment="Top"
       Width="200" Height="200"
       Stretch="Fill"
       Source="Assets/StoreLogo.png"
       PointerPressed="SourceImage_PointerPressed"/>
// Page_A.xaml.cs

private void SourceImage_PointerPressed(object sender, PointerRoutedEventArgs e)
{
    // Navigate to detail page.
    // Suppress the default animation to avoid conflict with the connected animation.
    Frame.Navigate(typeof(Page_B), null, new SuppressNavigationTransitionInfo());
}

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    ConnectedAnimationService.GetForCurrentView()
        .PrepareToAnimate("forwardAnimation", SourceImage);
    // You don't need to explicitly set the Configuration property because
    // the recommended Gravity configuration is default.
    // For custom animation, use:
    // animation.Configuration = new BasicConnectedAnimationConfiguration();
}

在目的地頁面中啟動動畫。

<!-- Page_B.xaml -->

<Image x:Name="DestinationImage"
       Width="400" Height="400"
       Stretch="Fill"
       Source="Assets/StoreLogo.png" />
// Page_B.xaml.cs

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    ConnectedAnimation animation =
        ConnectedAnimationService.GetForCurrentView().GetAnimation("forwardAnimation");
    if (animation != null)
    {
        animation.TryStart(DestinationImage);
    }
}

向後瀏覽

對於向後瀏覽 (Page_B 到 Page_A),您可以執行相同的步驟,但來源頁面和目標頁面相反。

當使用者返回時,他們會希望應用程式盡快返回到先前的狀態。 因此,建議的設定為 DirectConnectedAnimationConfiguration。 此動畫更快速、更直接,並且使用減速緩動。

在來源頁面中設定動畫。

// Page_B.xaml.cs

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    if (e.NavigationMode == NavigationMode.Back)
    {
        ConnectedAnimation animation = 
            ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("backAnimation", DestinationImage);

        // Use the recommended configuration for back animation.
        animation.Configuration = new DirectConnectedAnimationConfiguration();
    }
}

在目的地頁面中啟動動畫。

// Page_A.xaml.cs

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    ConnectedAnimation animation =
        ConnectedAnimationService.GetForCurrentView().GetAnimation("backAnimation");
    if (animation != null)
    {
        animation.TryStart(SourceImage);
    }
}

在設定動畫和啟動動畫的時間之間,來源元素會出現凍結在應用程式中的其他 UI 上方。 這可讓您同時執行任何其他轉換動畫。 基於這個理由,您不應該在兩個步驟之間等候超過 250 毫秒,因為來源元素的存在可能會分散注意力。 如果您準備了一個動畫,但沒有在三秒鐘內啟動它,系統將處置該動畫,並且對 TryStart 的任何後續呼叫都將失敗。

在清單和格線體驗中連接動畫

通常,您會希望從清單或格線控制項建立連接動畫,或建立連接到清單或格線控制項的動畫。 您可以使用 ListViewGridView 上的兩個方法 (PrepareConnectedAnimationTryStartConnectedAnimationAsync) 來簡化此過程。

例如,假設您有一個 ListView,其資料範本中包含一個名為「PortraitEllipse」的元素。

<ListView x:Name="ContactsListView" Loaded="ContactsListView_Loaded">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="vm:ContactsItem">
            <Grid>
                …
                <Ellipse x:Name="PortraitEllipse" … />
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

若要準備具有與指定清單項目對應之橢圓的連接動畫,請使用唯一索引鍵、項目和名稱「PortraitEllipse」呼叫 PrepareConnectedAnimation 方法。

void PrepareAnimationWithItem(ContactsItem item)
{
     ContactsListView.PrepareConnectedAnimation("portrait", item, "PortraitEllipse");
}

若要以此元素作為目標啟動動畫 (例如從詳細檢視瀏覽回來時),請使用 TryStartConnectedAnimationAsync。 如果剛剛載入 ListView 的資料來源,TryStartConnectedAnimationAsync 將等待建立對應的項目容器後開始動畫。

private async void ContactsListView_Loaded(object sender, RoutedEventArgs e)
{
    ContactsItem item = GetPersistedItem(); // Get persisted item
    if (item != null)
    {
        ContactsListView.ScrollIntoView(item);
        ConnectedAnimation animation =
            ConnectedAnimationService.GetForCurrentView().GetAnimation("portrait");
        if (animation != null)
        {
            await ContactsListView.TryStartConnectedAnimationAsync(
                animation, item, "PortraitEllipse");
        }
    }
}

協調動畫

Coordinated Animation

協調動畫是一種特殊的入口動畫類型,其中元素與連接動畫目標一起出現,並隨著連接動畫元素在畫面上移動而產生動畫效果。 協調的動畫可以為轉換添加更多視覺趣味效果,並進一步吸引使用者注意來源和目的地檢視之間共用的內容。 在這些影像中,項目的標題 UI 會使用協調動畫來產生動畫效果。

當協調動畫使用重力設定時,重力會同時套用至連接動畫元素和協調元素。 協調的元素將沿著連接的元素「飛過去」,讓元素保持真正的協調。

使用 TryStart 的兩參數多載,將協調元素新增至連接的動畫。 此範例示範了名為「DescriptionRoot」的格線佈局的協調動畫,該版面配置會與名為「CoverImage」的連接動畫元素串聯輸入。

<!-- DestinationPage.xaml -->
<Grid>
    <Image x:Name="CoverImage" />
    <Grid x:Name="DescriptionRoot" />
</Grid>
// DestinationPage.xaml.cs
void OnNavigatedTo(NavigationEventArgs e)
{
    var animationService = ConnectedAnimationService.GetForCurrentView();
    var animation = animationService.GetAnimation("coverImage");

    if (animation != null)
    {
        // Don’t need to capture the return value as we are not scheduling any subsequent
        // animations
        animation.TryStart(CoverImage, new UIElement[] { DescriptionRoot });
     }
}

可行與禁止事項

  • 在頁面轉換中使用連接動畫,其中元素在來源頁面和目標頁面之間共用。
  • 使用 GravityConnectedAnimationConfiguration 進行向前瀏覽。
  • 使用 DirectConnectedAnimationConfiguration 進行向後瀏覽。
  • 在準備和啟動連接動畫之間,請勿等待網路要求或其他長時間執行的非同步作業。 您可能需要預先載入必要的資訊,才能事先執行轉換,或在目的地檢視中載入高解析度影像時使用低解析度預留位置影像。
  • 如果您使用 ConnectedAnimationService,請使用 SuppressNavigationTransitionInfo 來阻止 Frame 中的轉換動畫,因為連接的動畫並不代表要與預設瀏覽轉換同時使用。 有關如何使用瀏覽轉換的更多資訊,請參閱 NavigationThemeTransition

ConnectedAnimation

ConnectedAnimationService

NavigationThemeTransition