Skip to content

Instantly share code, notes, and snippets.

@Sirelon
Forked from rlac/Spannable.kt
Last active December 16, 2019 10:02
Show Gist options
  • Save Sirelon/2773a8dc51cc8322e473c5fd5b9e6802 to your computer and use it in GitHub Desktop.
Save Sirelon/2773a8dc51cc8322e473c5fd5b9e6802 to your computer and use it in GitHub Desktop.
Adaptive for new Kotlin Version. A simple Kotlin builder for creating SpannableStrings. Original idea from https://gist.github.com/JakeWharton/11274467.
val span = spannable {
+"'spannable' makes it "
typeface(android.graphics.Typeface.ITALIC) {
+" easy "
}
+" to build a "
typeface(android.graphics.Typeface.BOLD) {
+" SpannableString "
}
+" without needing to touch SpannableStringBuilder."
+"\n\n"
+"It supports any type of span, and they can be nested!"
+"\n\n"
span(android.text.style.URLSpan("http://www.google.com")) {
+"www."
typeface(android.graphics.Typeface.BOLD) {
+"google"
}
+".com"
}
}
val textView = findViewById(R.id.text) as TextView
textView.setText(span.toCharSequence())
// Copyright 2014 Robert Carr
// Copyright 2016 Alexandr Romanishin
// 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.
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.StyleSpan
import java.util.*
fun spannable(init: SpanWithChildren.() -> Unit): SpanWithChildren {
val spanWithChildren = SpanWithChildren()
spanWithChildren.init()
return spanWithChildren
}
abstract class Span {
abstract fun render(builder: SpannableStringBuilder)
fun toCharSequence(): SpannableStringBuilder {
val builder = SpannableStringBuilder()
render(builder)
return builder
}
}
class SpanWithChildren(val what: Any? = null) : Span() {
val children = ArrayList<Span>()
fun color(color: Int, init: SpanWithChildren.() -> Unit): SpanWithChildren = span(ForegroundColorSpan(color), init)
fun typeface(typeface: Int, init: SpanWithChildren.() -> Unit): SpanWithChildren =
span(StyleSpan(typeface), init)
fun span(what: Any, init: SpanWithChildren.() -> Unit): SpanWithChildren {
var child = SpanWithChildren(what)
child.init()
children.add(child)
return this
}
operator fun String.unaryPlus() {
children.add(SpanWithText(this))
}
override fun render(builder: SpannableStringBuilder) {
val start = builder.length
for (c in children) {
c.render(builder)
}
if (what != null) {
builder.setSpan(what, start, builder.length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
}
}
}
class SpanWithText(val content: Any) : Span() {
override fun render(builder: SpannableStringBuilder) {
builder.append(content.toString())
}
}
@Mr-Ramzan
Copy link

Much appreciated.
Really helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment