為文字逐字加入動畫效果

您可以逐字元為文字外觀加入動畫效果,讓文字看起來像是打字機的輸入效果。

版本相容性

這個實作方式需要將專案 minSDK 設為 API 級別 21 以上。

依附元件

為文字逐字元加入動畫效果

這個程式碼會逐字元為文字製作動畫。它會追蹤索引,以控制要顯示多少文字。系統會動態更新顯示的文字,只顯示目前索引的字元。最後,變數會在變更時執行動畫。

@Composable
private fun AnimatedText() {
    val text = "This text animates as though it is being typed \uD83E\uDDDE\u200D♀\uFE0F \uD83D\uDD10  \uD83D\uDC69\u200D❤\uFE0F\u200D\uD83D\uDC68 \uD83D\uDC74\uD83C\uDFFD"

    // Use BreakIterator as it correctly iterates over characters regardless of how they are
    // stored, for example, some emojis are made up of multiple characters.
    // You don't want to break up an emoji as it animates, so using BreakIterator will ensure
    // this is correctly handled!
    val breakIterator = remember(text) { BreakIterator.getCharacterInstance() }

    // Define how many milliseconds between each character should pause for. This will create the
    // illusion of an animation, as we delay the job after each character is iterated on.
    val typingDelayInMs = 50L

    var substringText by remember {
        mutableStateOf("")
    }
    LaunchedEffect(text) {
        // Initial start delay of the typing animation
        delay(1000)
        breakIterator.text = StringCharacterIterator(text)

        var nextIndex = breakIterator.next()
        // Iterate over the string, by index boundary
        while (nextIndex != BreakIterator.DONE) {
            substringText = text.subSequence(0, nextIndex).toString()
            // Go to the next logical character boundary
            nextIndex = breakIterator.next()
            delay(typingDelayInMs)
        }
    }
    Text(substringText)

程式碼的重點

  • BreakIterator 會正確疊代字元,不論字元儲存方式為何。舉例來說,動畫表情符號由多個字元組成;BreakIterator 可確保系統以單一字元處理這些表情符號,避免動畫中斷。
  • LaunchedEffect 會啟動協同程式,在字元之間加入延遲時間。您可以使用點擊事件或任何其他事件,取代程式碼區塊,以觸發動畫。
  • 每次更新 substringText 的值時,Text 可組合函式都會重新轉譯。

結果

圖 1. 文字和表情符號逐字元動畫。

包含此指南的集合

本指南是精選的快速指南系列之一,涵蓋更廣泛的 Android 開發目標:

文字是任何 UI 的核心部分。瞭解在應用程式中顯示文字的不同方式,以提供優質的使用者體驗。
本系列影片將介紹各種 Compose API,快速向您展示可用的 API 和使用方式。

有問題或意見回饋嗎?

請前往常見問題頁面,瞭解快速指南或與我們聯絡,分享您的想法。