SOUI3.0仿Android插值動畫使用方法


在Android系統中,有插值動畫,數值動畫,屬性動畫,幀動畫。

幀動畫,在SOUI里可以通過AnimateImg這個控件來實現,其它幾種動畫3.0之前不支持,需要類似動畫效果,只能自己通過定時器去實現,實現成本比較高。

SOUI3.0增加了插值動畫和數值動畫支持,屬性動畫可以通過數值動畫來實現,因此沒有專門移植。

這一講我先講插值動畫。

有Android開發經驗的朋友,應該知道Android的插值動畫有AlphaAnimation, TranslationAnimation, ScaleAnimation, RotateAnimation, AnimationSet這5個類,它們都有共同的基類Animation。

3.0把這些Animation都移植到了SOUI。

在SOUI使用插值動畫和Android中類似,先通過XML定義好一個動畫,然后加載動畫,再交給SWindow去播放動畫。

下面以AnimationSet為例來說明如何使用。

1、定義動畫XML:

<?xml version="1.0" encoding="utf-8"?>
<set repeatCount="-1">
  <alpha duration="500" fromAlpha="1.0" toAlpha="0.5" repeatCount="1" repeatMode="reverse"/>
  <rotate duration="500" startOffset="1000" fromDegrees="0" toDegrees="360" pivotX="50%" pivotY="50%" repeatMode="restart" repeatCount="0"
        interpolator="linear"/>
  <set startOffset="1500">
    <scale duration="500"  fromXScale="1.0f" toXScale="0.5" fromYScale="1.0" toYScale="0.5" repeatCount="1" repeatMode="reverse"/>
  </set>
</set>

上面代碼來自demo\uires\Anim\rotate.xml

這個XML描述的是一個AnimationSet動畫,里面包含了一個AlphaAnimation,一個RotateAnimation及另一個包含ScaleAnimation的AnimationSet。

首先可以看到最外層的set有一個repeatCount屬性,值為-1,代表無限重復。

然后我們注意到這里第一個alpha動畫,duration=500代表這個動畫執行一次需要500ms, 再注意它有一個repeatCount=1,代表這個動畫執行2次,repeatMode=reverse,代表這個動畫第一次alpha從1.0到0.5, 第二次重復的時候變成從0.5到1.0。

然后我們注意一下第二個rotate動畫,它多了一個startOffset=1000,這個1000正好是上一個動畫的總執行時間,也就是說這個rotate動畫是在alpha動畫完成之后再執行。fromDegree, toDegree, pivotX, pivotY是rotate動畫的專有屬性,含義見代碼。這里注意一下interpolator屬性,interpolator代碼插值器類型,如果不指定這個屬性,系統默認使用AccelerateDecelerate插值器,這個插值器是先加速再減速。上面例子則調整為線性插值器。

最后再看它的第3個子動畫,它也是一個set動畫。它從1500MS開始,正好是上一個rotate動畫結束。這個set里只有一個scale動畫,它先縮小到50%,后放大100%。

整個動畫過程分成了3段,它們在時間是連續的,總共執行2500MS。

當然這些子動畫完全可以同步進行,也可以不連續。

2、加載動畫:

和所有SOUI其它資源一樣,首先這個XML應該放到uires目錄下,並且在uires.idx文件能夠正確引用到這個文件。

<anim>
    <file name="love" path="anim\love.xml"/>
    <file name="slide_show" path="anim\slide_show.xml"/>
    <file name="slide_hide" path="anim\slide_hide.xml"/>
    <file name="rotate" path="anim\rotate.xml"/>
  </anim>

最后一個name=rotate就是這個動畫資源。

配置好資源,就可以在代碼中引用這個動畫了:

void CMainDlg::InitSoui3Animation()
{
    SWindow *pWnd = FindChildByName(L"img_soui");
    if (pWnd)
    {
        IAnimation *pAni = SApplication::getSingletonPtr()->LoadAnimation(L"anim:rotate");
        if(pAni)
        {
            pWnd->SetAnimation(pAni);
            pAni->Release();
        }
    }
}

通過SAppliation::LoadAnimation來加載這個動畫。

3、將這個動畫交給SWindow來播放。注意上面代碼中的pWnd->SetAnimation,這樣這個動畫就會立即播放。SetAnimation會在SWindow內部持有這個IAnimation,因此這里還需要調用pAni->Release(),以保證動畫資源不使用后能釋放內存。如果希望動畫延時播放,可以調用pAni->SetStartOffset()來配置。

 

下圖是這個動畫在demo中的執行效果:

截圖時間軸不太准確,具體見demo。

注意:SOUI的AnimationSet和Android的AnimationSet有兩個區別:

1、SOUI的AnimationSet支持repeatCount屬性,但不支持repeatMode屬性。

2、和SOUI相反,Android的AnimationSet支持repeatMode屬性,但不支持repeatCount屬性。

實際上Android的repeatMode屬性意義不大,它不過是把這個屬性直接傳遞給它的子動畫對象,並不是作用於AnimationSet本身。考慮到如果和Android一樣支持repeatMode傳遞給子對象可能會產生誤解,SOUI中干脆就不支持這個屬性了。需要的話,直接在子對象上設置這個屬性就好了。

 

啟程軟件  2019年8月4日

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM