上一篇介紹了插值動畫,插值動畫是直接作用於窗口對象的。
數值動畫則可以作用於任何對象。
SOUI內置了3種數值類型的動畫,分別是SIntAnimator, SFloatAnimator, SColorAnimator,分別對應int, float, COLOR這3種數據類型,當然用戶也可以擴展支持其它數據類型,不過基本上這3種就足夠了。
下面以demo中使用的ColorAnimator為例來介紹如何使用數值動畫。
首先,和插值動畫一樣,我們需要一個XML來描述這個動畫。
<?xml version="1.0" encoding="utf-8"?> <colorAnimator duration="1000" valueFrom="RGBA(0,0,0,128)" valueTo="RGBA(255,0,0,128)" repeatCount="1" repeatMode="reverse"/>
上面是一個colorAnimator, 它描述了一個將顏色值從rgba(0,0,0,128)變化為rgba(255,0,0,128)的動畫,一次動畫持續1秒,再加一次重復,這個動畫一共2秒。
定義好動畫后,我們需要在代碼中加載這個動畫:
void CMainDlg::OnSouiClick() { IValueAnimator * pAni = SApplication::getSingletonPtr()->LoadValueAnimator(L"valueAni:colorAni"); if(pAni) { pAni->addListener(this); pAni->addUpdateListener(this); pAni->start(this); } }
上面代碼首先從ValueAni:colorAni指定的XML資源里加載並創建一個IVaueAnimator對象,創建成功以后,調用pAni->addUpdateListener(this)來設置動畫回調。然后調用pAni->start(this)來啟動動畫。
注意這里這個pAni對象沒有被其它對象持有。所以在這里start完成后,並不能直接release。
第三步,就是響應數值變化:
Demo中CMainDlg實現了IValueAnimator::IAnimatorUpdateListener接口,這個接口只有一個方法:
struct IAnimatorUpdateListener { virtual void onAnimationUpdate(IValueAnimator *pAnimator) = 0; };
這個方法在CMainDlg中的實現如下:
void CMainDlg::onAnimationUpdate(IValueAnimator *pAnimator) { SWindow *pTst = FindChildByName(L"tree_test"); if(pTst) { SColorAnimator *ani = sobj_cast<SColorAnimator>(pAnimator); if(ani) { SStringW strColor; SColor cr(ani->getValue()); strColor.Format(L"RGBA(%d,%d,%d,%d)",cr.r,cr.g,cr.b,cr.a); pTst->SetAttribute(L"colorBkgnd",strColor); } } }
我們首先找到tree_test這個控件,在這個動畫過程中,我們通過動畫獲得一個顏色值,再用這個顏色值來改變tree_test的背景顏色。這里實際上相當於實現了一個Android的屬性動畫。
最后,在動畫完成的時候,我們做下面的處理:
void CMainDlg::onAnimationEnd(IValueAnimator * pAnimator) { SWindow *pTst = FindChildByName(L"tree_test"); if(pTst) { pTst->SetAttribute(L"colorBkgnd",L"RGBA(255,255,255,0)");//set invalid colorBkgnd pAnimator->Release(); } }
在這里,我們把tree_test的背景色恢復成不使用背景,再調用pAnimator->Release()來釋放數據動畫對象。
下面看一下數值動畫運行的效果。
這是一個簡單的數據動畫的demo,雖然例子很簡單,實際上用戶可以使用它完成各種任務,這里不再一一舉例。
啟程軟件 2019年8月4日