This repository was archived by the owner on Nov 14, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 560
Expand file tree
/
Copy pathSpannableStringBuilder.kt
More file actions
165 lines (150 loc) · 5.46 KB
/
SpannableStringBuilder.kt
File metadata and controls
165 lines (150 loc) · 5.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.core.text
import android.graphics.Typeface.BOLD
import android.graphics.Typeface.ITALIC
import android.text.Spannable.SPAN_INCLUSIVE_EXCLUSIVE
import android.text.SpannableStringBuilder
import android.text.SpannedString
import android.text.style.BackgroundColorSpan
import android.text.style.ForegroundColorSpan
import android.text.style.RelativeSizeSpan
import android.text.style.StrikethroughSpan
import android.text.style.StyleSpan
import android.text.style.SubscriptSpan
import android.text.style.SuperscriptSpan
import android.text.style.URLSpan
import android.text.style.UnderlineSpan
import androidx.annotation.ColorInt
/**
* Builds new string by populating a newly created [SpannableStringBuilder] using the provided
* [builderAction] and then converting it to [SpannedString].
*/
inline fun buildSpannedString(builderAction: SpannableStringBuilder.() -> Unit): SpannedString {
val builder = SpannableStringBuilder()
builder.builderAction()
return SpannedString(builder)
}
/**
* Wrap appended text in [builderAction] in [spans].
*
* Note: the spans will only have the correct position if the [builderAction] only appends or
* replaces text. Inserting, deleting, or clearing the text will cause the span to be placed at
* an incorrect position.
*/
inline fun SpannableStringBuilder.inSpans(
vararg spans: Any,
builderAction: SpannableStringBuilder.() -> Unit
): SpannableStringBuilder {
val start = length
builderAction()
for (span in spans) setSpan(span, start, length, SPAN_INCLUSIVE_EXCLUSIVE)
return this
}
/**
* Wrap appended text in [builderAction] in [span].
*
* Note: the span will only have the correct position if the `builderAction` only appends or
* replaces text. Inserting, deleting, or clearing the text will cause the span to be placed at
* an incorrect position.
*/
inline fun SpannableStringBuilder.inSpans(
span: Any,
builderAction: SpannableStringBuilder.() -> Unit
): SpannableStringBuilder {
val start = length
builderAction()
setSpan(span, start, length, SPAN_INCLUSIVE_EXCLUSIVE)
return this
}
/**
* Wrap appended text in [builderAction] in a bold [StyleSpan].
*
* @see SpannableStringBuilder.inSpans
*/
inline fun SpannableStringBuilder.bold(builderAction: SpannableStringBuilder.() -> Unit) =
inSpans(StyleSpan(BOLD), builderAction = builderAction)
/**
* Wrap appended text in [builderAction] in an italic [StyleSpan].
*
* @see SpannableStringBuilder.inSpans
*/
inline fun SpannableStringBuilder.italic(builderAction: SpannableStringBuilder.() -> Unit) =
inSpans(StyleSpan(ITALIC), builderAction = builderAction)
/**
* Wrap appended text in [builderAction] in an [UnderlineSpan].
*
* @see SpannableStringBuilder.inSpans
*/
inline fun SpannableStringBuilder.underline(builderAction: SpannableStringBuilder.() -> Unit) =
inSpans(UnderlineSpan(), builderAction = builderAction)
/**
* Wrap appended text in [builderAction] in an [URLSpan].
*
* @see SpannableStringBuilder.inSpans
*/
inline fun SpannableStringBuilder.url(
url: String,
builderAction: SpannableStringBuilder.() -> Unit
) = inSpans(URLSpan(url), builderAction = builderAction)
/**
* Wrap appended text in [builderAction] in a [ForegroundColorSpan].
*
* @see SpannableStringBuilder.inSpans
*/
inline fun SpannableStringBuilder.color(
@ColorInt color: Int,
builderAction: SpannableStringBuilder.() -> Unit
) = inSpans(ForegroundColorSpan(color), builderAction = builderAction)
/**
* Wrap appended text in [builderAction] in a [BackgroundColorSpan].
*
* @see SpannableStringBuilder.inSpans
*/
inline fun SpannableStringBuilder.backgroundColor(
@ColorInt color: Int,
builderAction: SpannableStringBuilder.() -> Unit
) = inSpans(BackgroundColorSpan(color), builderAction = builderAction)
/**
* Wrap appended text in [builderAction] in a [StrikethroughSpan].
*
* @see SpannableStringBuilder.inSpans
*/
inline fun SpannableStringBuilder.strikeThrough(builderAction: SpannableStringBuilder.() -> Unit) =
inSpans(StrikethroughSpan(), builderAction = builderAction)
/**
* Wrap appended text in [builderAction] in a [RelativeSizeSpan].
*
* @see SpannableStringBuilder.inSpans
*/
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)