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>

上面代码来自demouiresAnim otate.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="animlove.xml"/>
    <file name="slide_show" path="animslide_show.xml"/>
    <file name="slide_hide" path="animslide_hide.xml"/>
    <file name="rotate" path="anim
otate.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日

原文地址:https://www.cnblogs.com/setoutsoft/p/11298908.html