第二十二章:动画(十四)
你自己的等待動畫
在本章的下一節中,您將看到Xamarin.Forms實現的基礎動畫基礎結構。這些底層方法允許您定義自己的動畫函數,這些函數返回Task對象,并且可以與await一起使用。
在第20章“異步和文件I / O”中,您了解了如何使用靜態Task.Run方法創建執行的輔助線程,以執行像Mandelbrot計算這樣的密集后臺作業。 Task.Run方法返回一個Task對象,該對象可以在后臺作業完成時發出信號。
但動畫并不是那樣的。動畫不需要花費大量時間來處理數字。它只需要做一些非常簡單和簡單的事情 - 比如設置一個Rotation屬性 - 每16毫秒一次。該作業可以在用戶界面線程中運行 - 事實上,實際的屬性訪問必須在用戶界面線程中運行 - 并且可以使用Device.StartTimer或Task.Delay來處理時間。
您不應該使用Task.Run來實現動畫,因為執行的輔助線程是不必要的并且是浪費的。但是,當您實際坐下來編寫類似于Xamarin.Forms動畫方法(如RotateTo)的動畫方法時,您可能會遇到障礙。該方法必須返回一個Task對象,并且可能使用Device.StartTimer作為計時,但這似乎不可能。
這是第一次嘗試編寫這樣的方法。 參數包括目標VisualElement,from和to值以及持續時間。 它使用Device.StartTimer和Stopwatch來計算Rotation屬性的當前設置,并在動畫完成時退出Device.StartTimer回調:
在兩個關鍵點上,該方法不知道該怎么做。在方法調用Device.StartTimer之后,它需要退出并將Task對象返回給調用者。但是這個Task對象來自哪里? Task類有一個構造函數,但是像Task.Run一樣,該構造函數創建了第二個執行線程,并且沒有理由創建該線程。此外,當動畫結束時,該方法需要以某種方式表示任務已完成。
幸運的是,存在一個完全符合您要求的類。 它叫做TaskCreationSource。 它是一個泛型類,其中type參數與要創建的Task對象的type參數相同。 askCreationSource對象的Task屬性提供了您需要的Task對象。 這是您的異步方法返回的內容。 當您的方法完成處理后臺作業時,它可以在TaskCreationSource對象上調用SetResult,表示作業已完成。
以下TryAwaitableAnimation程序顯示如何在從Button的Clicked處理程序調用的MyRotateTo方法中使用TaskCreationSource:
注意TaskCreationSource的實例化,該對象的Task屬性的返回值,以及動畫完成后對Device.StartTimer回調內的SetResult的調用。
TaskCreationSource沒有非通用形式,因此如果您的方法只返回Task對象而不是Task 對象,則在定義TaskCreationSource實例時需要指定類型。 按照慣例,您可以使用object來實現此目的,在這種情況下,您的方法使用null參數調用SetResult。
TryAwaitableAnimation XAML文件實例化共享此Clicked處理程序的三個Button元素。 它們中的每一個都將自己的動畫持續時間定義為StyleId屬性。 (正如您所記得的,StyleId不在Xamarin.Forms中使用,僅供應用程序員使用,作為將任意數據附加到元素的便捷方式。)
即使這些Button元素中的每一個都通過調用MyRotate來設置動畫,您也可以讓所有按鈕同時旋轉。每次調用MyRotate都會獲得自己的局部變量集,并在每個Device.StartTimer回調中使用這些局部變量。
但是,如果在按鈕仍處于旋轉狀態時點擊按鈕,則會向該按鈕應用第二個動畫,并且兩個動畫相互爭斗。代碼需要的是在應用新動畫時取消上一個動畫的方法。
一種方法是MyRotate方法維護Dictionary 定義為字段。每當它開始動畫時,MyRotate都會將目標VisualElement作為該字典的鍵添加,其值為false。動畫結束時,它會從字典中刪除此條目。一個單獨的方法(可能名為CancelMyRotate)可以將字典中的值設置為true,這意味著取消動畫。 Device.StartTimer回調可以通過檢查特定VisualElement的字典值開始,如果動畫已被取消,則從回調返回false。但是你會在討論中發現如何用更少的代碼來完成它。
現在您已經看到了ViewExtensions類中實現的高級動畫函數,讓我們來探討Xamarin.Forms動畫系統的其余部分如何實現這些函數
并允許您啟動,控制和取消動畫。
總結
以上是生活随笔為你收集整理的第二十二章:动画(十四)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从构建分布式秒杀系统聊聊验证码
- 下一篇: m4-第8周作业