iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 9
0
自我挑戰組

學習 Android Kotlin 隨筆系列 第 9

[ Day 9 ] 探討 Fragment 從年少輕狂,到老年退休生活!(四)樸實無華但有質感,開場動畫

  • 分享至 

  • xImage
  •  

| 實作 code

  • 連結 | Android 專案
    • @commit aeaf1f8

| 生命週期

  • 連結 | 旋轉跳躍

  • 連結 | 忍術!變身術

  • 樸實無華但有質感,開場動畫跟音效

| 實作概念

以下是比較精簡的實作方法

  • 設定動畫的監聽 (animation listener)

    在上一篇是說,想要實作出 fade in 跟 fade out 的感覺,所以監聽 fade in 的結束,並且在結束的時候立馬接上 fade out。

    因為寫了兩個動畫綁定,太冗長了。後來更正另一個作法,其實 fade out 就是 fade in 反過來做而已,所以實際上我只做了一個 fade in ,並且重複 (repeat) 它,在重複的時候把它換成 reverse,就會有這種效果出現了,如以下程式碼

    <alpha android:fromAlpha="0.0"
           android:toAlpha="1.0"
           android:duration="2000"
           android:repeatMode="reverse"
           android:repeatCount = "1"
           >
    </alpha>
    

    這樣,就直接省去了把兩個動畫使用很冗長的方法綁在一起,而只要寫一個 listener 就好了。

  • 動畫的結尾樣子

    這個動畫的結尾是 fade out,整個圖片會消失。但是並沒有如想像一般,當動畫全部結束之後,會回到該圖片預設狀態,也就是淡掉之後又整張再顯示出來。這時原先的處理方式就是直接設定為 INVISIBLE,但後來發現另一個好的方法,就是把 fillAfter 設為 true,那麼就會把動畫的最後一幕套用在該圖上面,也就是說,如果最後一幕是全部淡掉的,那麼就直接套用進去該圖,而不是使用他預設的值,參考連結

    android:fillAfter = "true"
    
  • 動畫音效

    這邊我使用了兩種方法實作出來,一種是 MediaPlayer.create,另一種是 SoundPool。兩種方法大同小異,使用 MediaPlayer.create 比較單純,單純放一首歌,放一小段預設好的音效,而 SoundPool 則是一個能夠裝很多音效的方法。這邊先設定音效是無限循環,當動畫結束之後就去停止他。

    • MediaPlayer

      mp = MediaPlayer.create(this, R.raw.star)
      mp?.isLooping = true
      mp?.setOnPreparedListener {
          Log.d("", "music is prepared")
          mp?.start()
          setStartAnim()
      }
      
    • SoundPool

      private var sp = SoundPool.Builder().setMaxStreams(8).build();
      private val sounds = mutableListOf<Int>()
      
      sounds.add(sp.load(this, R.raw.star, 1))
      sp.setOnLoadCompleteListener { soundPool, sampleId, status ->
          soundPool.play(sounds[0], 1.0f, 1.0f, 1, -1, 1.0f)
          setStartAnim()
      }
      

| 實作小泥坑

  • 為何音效出不來呢?

    自己在 onCreate() 的動畫時,已經寫下了以下 code,為何沒有任何聲音出現呢?

    soundPool.play(sounds[0], 1.0f, 1.0f, 1, -1, 1.0f)
    

    原來在載入音效的時候,因為載入很需要時間,所以會以 非同步 (asynchronous) 的方式去做載入。意思就是說,在做載入聲音的這個麻煩事情,主程式會生出另一個 thread,姑且把它當作小僕人好了,這個小僕人像是我的幫手,他去把音樂載進來,而我的主程式並不會等音樂載入,會直接繼續去做其他事情。

    這時候你就會發現,主程式會直接去做動畫,這時候,因為小僕人還沒有把音效弄好,所以自然而然不會有音樂!該怎辦呢?那就是主程式等著小僕人把音樂都準備好了,之後再去跑動畫,程式碼就該改成下面的樣子

    sp.setOnLoadCompleteListener { soundPool, sampleId, status ->
        soundPool.play(sounds[0], 1.0f, 1.0f, 1, -1, 1.0f)
        setStartAnim()
    }
    

    當音樂確定完成載入,才會去執行裡面的 play 以及啟動動畫的部分唷!


上一篇
[ Day 8 ] 探討 Fragment 從年少輕狂,到老年退休生活!(三)樸實無華但有質感,開場動畫
下一篇
[ Day 10 ] 是 View Pager 啊 (一)左滑滑,右滑滑
系列文
學習 Android Kotlin 隨筆30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言