From 69588da665f8dbebb20206619e2282fc659fa853 Mon Sep 17 00:00:00 2001 From: dmail Date: Mon, 16 Sep 2024 11:33:42 -0700 Subject: [PATCH 1/5] Code snippet for Compose doc at https://developer.android.com/quick-guides/content/animate-text?hl=en (Animate text character-by-character). Code taken from riggaroo gist at https://www.google.com/url?sa=D&q=https%3A%2F%2Fgist.github.com%2Friggaroo%2F668868c954c4a1e9b29fa57a762e63b5 --- .../snippets/animations/AnimationSnippets.kt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt index 9db1748d1..a7e967a76 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt @@ -109,6 +109,9 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import com.example.compose.snippets.R +import kotlinx.coroutines.delay +import java.text.BreakIterator +import java.text.StringCharacterIterator /* * Copyright 2023 The Android Open Source Project @@ -820,3 +823,38 @@ private fun Expanded() { @Composable private fun ContentIcon() { } + +@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) +// [END android_compose_animations_animate_char_by_char +} From 783b770a46c37e4155678417d4fb9ead312cb347 Mon Sep 17 00:00:00 2001 From: thedmail Date: Mon, 16 Sep 2024 18:36:47 +0000 Subject: [PATCH 2/5] Apply Spotless --- .../example/compose/snippets/animations/AnimationSnippets.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt index a7e967a76..74c5c078b 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt @@ -109,9 +109,9 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import com.example.compose.snippets.R -import kotlinx.coroutines.delay import java.text.BreakIterator import java.text.StringCharacterIterator +import kotlinx.coroutines.delay /* * Copyright 2023 The Android Open Source Project From 8b542c0dd5582e1316f2f03a199c0f21da2ab8d5 Mon Sep 17 00:00:00 2001 From: dmail Date: Tue, 24 Sep 2024 18:48:42 -0700 Subject: [PATCH 3/5] Fixes malformed region tags. --- .../example/compose/snippets/animations/AnimationSnippets.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt index a7e967a76..7aeff5d89 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt @@ -824,6 +824,7 @@ private fun Expanded() { private fun ContentIcon() { } +// [START android_compose_animations_vector_char_by_char] @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" @@ -856,5 +857,5 @@ private fun AnimatedText() { } } Text(substringText) -// [END android_compose_animations_animate_char_by_char +// [END android_compose_animations_animate_char_by_char] } From 4d0bd1f2933fc73f4d027923f3a6a57bce475ed6 Mon Sep 17 00:00:00 2001 From: dmail Date: Wed, 25 Sep 2024 13:28:11 -0700 Subject: [PATCH 4/5] Fixes region tags. --- .../compose/snippets/animations/AnimationSnippets.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt index c69afd451..9e915a62b 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt @@ -109,9 +109,9 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import com.example.compose.snippets.R +import kotlinx.coroutines.delay import java.text.BreakIterator import java.text.StringCharacterIterator -import kotlinx.coroutines.delay /* * Copyright 2023 The Android Open Source Project @@ -824,7 +824,7 @@ private fun Expanded() { private fun ContentIcon() { } -// [START android_compose_animations_vector_char_by_char] +// [START android_compose_animations_char_by_char] @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" @@ -857,5 +857,5 @@ private fun AnimatedText() { } } Text(substringText) -// [END android_compose_animations_animate_char_by_char] +// [END android_compose_animations_char_by_char] } From c5c65e1675386c0ad31870f1fe345e93573ec7f0 Mon Sep 17 00:00:00 2001 From: thedmail Date: Wed, 25 Sep 2024 20:29:54 +0000 Subject: [PATCH 5/5] Apply Spotless --- .../example/compose/snippets/animations/AnimationSnippets.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt index 9e915a62b..38a1eb44d 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt @@ -109,9 +109,9 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import com.example.compose.snippets.R -import kotlinx.coroutines.delay import java.text.BreakIterator import java.text.StringCharacterIterator +import kotlinx.coroutines.delay /* * Copyright 2023 The Android Open Source Project