<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ConstraintLayout2.0一篇寫不完之KeyCycles的秘密

          共 4768字,需瀏覽 10分鐘

           ·

          2021-09-03 18:05

          點(diǎn)擊上方藍(lán)字關(guān)注我,知識(shí)會(huì)給你力量


          KeyCycle與KeyFrame類似,但是又比KeyFrame復(fù)雜,復(fù)雜在于KeyFrame只是單幀,而KeyCycle則是在KeyFrame的基礎(chǔ)上,增加了周期性的處理,所以,KeyCycle的核心就是周期,KeyCycle決定了在Scene中所有需要重復(fù)處理的部分操作,它的核心API如下所示。

          • framePosition:作為一個(gè)KeyFrame,KeyCycle必須知道在場(chǎng)景的哪一點(diǎn)上進(jìn)行操作
          • motionTarget:指定的View ID
          • wavePeriod:周期數(shù)量
          • waveOffset:起始位置的偏移
          • waveShape:Cycle的波形
          image-20210827101705951

          MotionLayout提供了CycleEditor來(lái)幫助開發(fā)者編輯KeyCycle,下載地址如下:

          https://github.com/googlesamples/android-ConstraintLayoutExamples/releases/download/1.0/CycleEditor.jar

          直接執(zhí)行即可,點(diǎn)擊file中的parse,就可以將編輯區(qū)域的xml轉(zhuǎn)換為波形。

          java -jar CycleEditor.jar

          分割Scene

          在創(chuàng)建KeyCycle之前的第一件事,就是通過(guò)使用不同的framePositions把你的Scene分成多部分組合的Partial Scene,接下來(lái)就可以通過(guò)使用wavePeriod來(lái)指定你想要的每個(gè)部分的周期數(shù),以及waveShape來(lái)指定具體的波形。

          1*cdtzWO2JKu6VvmN9Ew2kvw

          wavePeriod是KeyCycle最難理解的一部分,要掌握wavePeriod的定義,就必須先了解Partial Scene,Partial Scene指的是當(dāng)前指定點(diǎn)的前一個(gè)點(diǎn)和后一個(gè)點(diǎn),總共三個(gè)點(diǎn)構(gòu)成的區(qū)域,這點(diǎn)非常重要。

          在某個(gè)framePosition的KeyCycle中指定wavePeriod,其實(shí)就是指在這個(gè)Partial Scene中,有幾個(gè)周期的波形來(lái)填滿這個(gè)區(qū)域。

          但是這里問(wèn)題又來(lái)了,每個(gè)framePosition都被周圍的framePosition有關(guān),那么wavePeriod不是被重復(fù)計(jì)算了嗎?

          沒錯(cuò)。。。所以在整個(gè)Partial Scene中的wavePeriod是由Partial Scene中所有framePosition的的wavePeriod之和確定的。很繞是不是,是就對(duì)了。

          這也是為什么KeyCycle有個(gè)單獨(dú)的生成工具的原因,結(jié)合KeyCycleEditor,還是比較能理解的。

          wavePeriod已經(jīng)很繞了,但是繞的還在后面。

          我們?cè)賮?lái)看看KeyCycle中指定的具體屬性值的含義。

          例如,我們?cè)贙eyCycle中指定rotation為20,代碼如下所示。

          <KeyCycle 
                  motion:framePosition="0"
                  motion:target="@+id/button"
                  motion:wavePeriod="0"
                  motion:waveOffset="0"
                  motion:waveShape="sin"
                  android:rotation="20"/>

          這個(gè)rotation為20是什么意思?你以為是當(dāng)然framePosition的屬性值為20嗎?太年輕了。。。

          其實(shí)這個(gè)屬性值與View在當(dāng)前framePosition的屬性值,并沒有直接聯(lián)系。。。

          是不是很奇怪,的確如此,那么這玩意兒到底是干嘛的呢???

          這里我們需要轉(zhuǎn)換一下思路,那就是KeyCycle里面設(shè)置的一切東西,都是為了畫出「波形圖」,所以,這些參數(shù)的設(shè)置,就是為了修改波形圖的具體形狀。

          <KeyFrameSet>

          <KeyCycle 
                  motion:framePosition="0"
                  motion:target="@+id/button"
                  motion:wavePeriod="0"
                  motion:waveOffset="0"
                  motion:waveShape="sin"
                  android:rotation="0"/>

          <KeyCycle 
                  motion:framePosition="50"
                  motion:target="@+id/button"
                  motion:wavePeriod="1"
                  motion:waveOffset="0"
                  motion:waveShape="sin"
                  android:rotation="10"/>

          <KeyCycle 
                  motion:framePosition="100"
                  motion:target="@+id/button"
                  motion:wavePeriod="0"
                  motion:waveOffset="0"
                  motion:waveShape="sin"
                  android:rotation="30"/>

          </KeyFrameSet>

          這樣一個(gè)KeyCycle最后形成的波形圖就是這樣。

          image-20210827151332911

          由此可以發(fā)現(xiàn),每個(gè)framePosition的屬性值,就是為了畫出波形圖的波峰。

          在這個(gè)的基礎(chǔ)上,waveOffset就好理解了,它的作用就是給framePosition的當(dāng)前value增加一個(gè)初始值,這個(gè)初始值同樣是為了修改波形。

          要干嘛

          你說(shuō)KeyCycle這玩意兒整這么復(fù)雜,到底有什么用呢??

          我們有了KeyFrame,可以用來(lái)添加中間態(tài)關(guān)鍵幀,那么還要KeyCycle干嘛呢?

          說(shuō)到這來(lái),就不能不提下Monotonic Spline(單調(diào)采樣)了,通常的關(guān)鍵幀插值算法都是使用的單調(diào)采樣,但是這樣無(wú)法做到曲線的圓滑過(guò)渡,就像下圖中的綠色曲線,這樣四個(gè)點(diǎn)使用單調(diào)采樣,就變成了下面這樣的曲線,過(guò)渡會(huì)非常生硬。

          image-20210827154425111

          那么為了讓曲線圓滑過(guò)渡,KeyCycle使用的是Typical Spline(特征采樣),就如上圖中的紫色曲線,四個(gè)點(diǎn)被圓滑的連接了起來(lái)。

          如果僅僅是為了讓曲線能圓滑過(guò)渡,那么你就太小看KeyCycle了,不得不說(shuō)老外做的這些東西,總能在一些你覺得無(wú)關(guān)緊要的地方,做的非常深入。

          KeyCycle的核心在于波形,而波是什么呢?

          image-20210827155302534

          上面這張圖表達(dá)了sin和cos的幾何含義,也是sin和cos的來(lái)源。

          說(shuō)句不像傅里葉變換的話,我們可以將一個(gè)View的曲線運(yùn)動(dòng),拆解成多個(gè)不同波形運(yùn)動(dòng)的疊加。

          例如我們對(duì)一個(gè)View的translationX同時(shí)設(shè)置sin和cos的KeyCycle,最終形成的運(yùn)動(dòng)軌跡,就是一個(gè)圓形!

          所以,由此及彼,我們可以復(fù)合多個(gè)屬性的同時(shí),通過(guò)不同的波形疊加,實(shí)現(xiàn)任何你想要的運(yùn)動(dòng)軌跡!這TM就牛逼了啊,簡(jiǎn)直就是傅里葉變換在Android動(dòng)畫中的實(shí)現(xiàn)了。

          在CycleEditor中,有一些自帶的Demo,可以讓你充分的了解這個(gè)思想,例如下面這個(gè)例子。

          image-20210827160218065

          太復(fù)雜了是嗎?

          CustomWave shape in keyCycle

          CL2.1之后,motion:waveShape除了之前定義的sin、cos、bounce這些預(yù)設(shè)曲線外,你還可以設(shè)置自定義的波形曲線,定義方式如下所示。

          <KeyCycle motion:waveShape=”spline(0.0, 1.0, -1.0, 0)” />

          這就有點(diǎn)牛逼了,本來(lái)就很復(fù)雜了,這下還來(lái)了自定義曲線,再見。

          KeyCycle確實(shí)比較強(qiáng)大,但是也非常復(fù)雜,強(qiáng)烈建議大家使用CycleEditor來(lái)學(xué)習(xí),KeyCycle這種東西,就像核武器一樣,可以不用,但是不能沒有。

          向大家推薦下我的網(wǎng)站 https://xuyisheng.top/  點(diǎn)擊原文一鍵直達(dá)

          專注 Android-Kotlin-Flutter 歡迎大家訪問(wèn)



          往期推薦


          本文原創(chuàng)公眾號(hào):群英傳,授權(quán)轉(zhuǎn)載請(qǐng)聯(lián)系微信(Tomcat_xu),授權(quán)后,請(qǐng)?jiān)谠瓌?chuàng)發(fā)表24小時(shí)后轉(zhuǎn)載。
          < END >
          作者:徐宜生

          更文不易,點(diǎn)個(gè)“三連”支持一下??


          瀏覽 40
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色婷| 欧美性爱永久免费 | 亚洲国产mv | 亚洲日韩欧美激情 | 亚洲A∨ |