diff --git a/api/current.txt b/api/current.txt index 6d0ac772..5d0355f0 100644 --- a/api/current.txt +++ b/api/current.txt @@ -391,7 +391,11 @@ package androidx.text { method public static android.text.SpannableStringBuilder italic(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1 builderAction); method public static android.text.SpannableStringBuilder scale(android.text.SpannableStringBuilder, float proportion, kotlin.jvm.functions.Function1 builderAction); method public static android.text.SpannableStringBuilder strikeThrough(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1 builderAction); + method public static android.text.SpannableStringBuilder subscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1 builderAction); + method public static android.text.SpannableStringBuilder superscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1 builderAction); + method public static android.text.SpannableStringBuilder typeface(android.text.SpannableStringBuilder, String family, kotlin.jvm.functions.Function1 builderAction); method public static android.text.SpannableStringBuilder underline(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1 builderAction); + method public static android.text.SpannableStringBuilder url(android.text.SpannableStringBuilder, String url, kotlin.jvm.functions.Function1 builderAction); } public final class SpannableStringKt { diff --git a/src/androidTest/java/androidx/text/SpannableStringBuilderTest.kt b/src/androidTest/java/androidx/text/SpannableStringBuilderTest.kt index b6d543e7..94c8c163 100644 --- a/src/androidTest/java/androidx/text/SpannableStringBuilderTest.kt +++ b/src/androidTest/java/androidx/text/SpannableStringBuilderTest.kt @@ -29,6 +29,8 @@ import android.text.style.RelativeSizeSpan import android.text.style.StyleSpan import android.text.style.SubscriptSpan import android.text.style.SuperscriptSpan +import android.text.style.TypefaceSpan +import android.text.style.URLSpan import android.text.style.UnderlineSpan import org.junit.Assert.assertEquals import org.junit.Assert.assertSame @@ -186,6 +188,76 @@ class SpannableStringBuilderTest { assertEquals(12, result.getSpanEnd(scale)) } + @Test fun builderUp() { + val result: SpannedString = buildSpannedString { + append("Hello, ") + superscript { + append("World") + } + } + assertEquals("Hello, World", result.toString()) + + val spans = result.getSpans() + assertEquals(1, spans.size) + + val up = spans.filterIsInstance().single() + assertEquals(7, result.getSpanStart(up)) + assertEquals(12, result.getSpanEnd(up)) + } + + @Test fun builderDown() { + val result: SpannedString = buildSpannedString { + append("Hello, ") + subscript { + append("World") + } + } + assertEquals("Hello, World", result.toString()) + + val spans = result.getSpans() + assertEquals(1, spans.size) + + val down = spans.filterIsInstance().single() + assertEquals(7, result.getSpanStart(down)) + assertEquals(12, result.getSpanEnd(down)) + } + + @Test fun builderFont() { + val result: SpannedString = buildSpannedString { + append("Hello, ") + typeface("serif") { + append("World") + } + } + assertEquals("Hello, World", result.toString()) + + val spans = result.getSpans() + assertEquals(1, spans.size) + + val font = spans.filterIsInstance().single() + assertEquals("serif", font.family) + assertEquals(7, result.getSpanStart(font)) + assertEquals(12, result.getSpanEnd(font)) + } + + @Test fun builderUrl() { + val result: SpannedString = buildSpannedString { + append("Hello, ") + url("http://www.google.com") { + append("World") + } + } + assertEquals("Hello, World", result.toString()) + + val spans = result.getSpans() + assertEquals(1, spans.size) + + val url = spans.filterIsInstance().single() + assertEquals("http://www.google.com", url.url) + assertEquals(7, result.getSpanStart(url)) + assertEquals(12, result.getSpanEnd(url)) + } + @Test fun nested() { val result: SpannedString = buildSpannedString { color(RED) { diff --git a/src/main/java/androidx/text/SpannableStringBuilder.kt b/src/main/java/androidx/text/SpannableStringBuilder.kt index 6bc9eb5c..e675e5eb 100644 --- a/src/main/java/androidx/text/SpannableStringBuilder.kt +++ b/src/main/java/androidx/text/SpannableStringBuilder.kt @@ -27,6 +27,10 @@ import android.text.style.ForegroundColorSpan import android.text.style.StrikethroughSpan import android.text.style.RelativeSizeSpan import android.text.style.StyleSpan +import android.text.style.SubscriptSpan +import android.text.style.SuperscriptSpan +import android.text.style.TypefaceSpan +import android.text.style.URLSpan import android.text.style.UnderlineSpan /** @@ -134,3 +138,39 @@ inline fun SpannableStringBuilder.scale( proportion: Float, builderAction: SpannableStringBuilder.() -> Unit ) = inSpans(RelativeSizeSpan(proportion), builderAction = builderAction) + +/** + * Wrap appended text in [builderAction] in a [SuperscriptSpan]. + * + * @see SpannableStringBuilder.inSpans + */ +inline fun SpannableStringBuilder.superscript(builderAction: SpannableStringBuilder.() -> Unit) = + inSpans(SuperscriptSpan(), builderAction = builderAction) + +/** + * Wrap appended text in [builderAction] in a [SubscriptSpan]. + * + * @see SpannableStringBuilder.inSpans + */ +inline fun SpannableStringBuilder.subscript(builderAction: SpannableStringBuilder.() -> Unit) = + inSpans(SubscriptSpan(), builderAction = builderAction) + +/** + * Wrap appended text in [builderAction] in a [TypefaceSpan]. + * + * @see SpannableStringBuilder.inSpans + */ +inline fun SpannableStringBuilder.typeface( + family: String, + builderAction: SpannableStringBuilder.() -> Unit +) = inSpans(TypefaceSpan(family), builderAction = builderAction) + +/** + * Wrap appended text in [builderAction] in a [URLSpan]. + * + * @see SpannableStringBuilder.inSpans + */ +inline fun SpannableStringBuilder.url( + url: String, + builderAction: SpannableStringBuilder.() -> Unit +) = inSpans(URLSpan(url), builderAction = builderAction)