Android Expandable Text like Instagram
I was developing an application similar to Instagram Feed that I was falling in trouble of how to implement an expandable TextView like the description of images on Instagram:

There was not a native component to accomplish this need, so after searching and reading articles, I find the following approach the best one:
The following function gets the full caption of an image without expandability as a SpannableStringBuilder with bold sender name, regular caption, and a space between them:
private fun getFullCaption(
senderName: String,
caption: String
) = SpannableStringBuilder()
.bold { append(senderName) }
.append(" ")
.append(caption)To add expandability to a TextView, I found the following solution best. You can modify the visible lines before expanding in DEFAULT_LINES parameter:
const val DEFAULT_LINES = 2private fun TextView.setCaption(senderName: String, caption: String) {
text = getFullCaption(senderName, caption) if (lineCount > DEFAULT_LINES) {
val lastCharShown = layout.getLineVisibleEnd(DEFAULT_LINES - 1)
maxLines = DEFAULT_LINES
val moreString = context.getString(R.string.read_more)
val suffix = " $moreString"
// 3 is a "magic number" but it's just basically the length of the ellipsis we're going to insert
val actionDisplayText = context.getString(R.string.more_dots) + suffix text = SpannableStringBuilder()
.bold { append(senderName) }
.append(" ")
.append(
caption.substring(
0,
lastCharShown - suffix.length - 3 - moreString.length - senderName.length
)
)
.color(Color.GRAY) { append(actionDisplayText) }
}
}
What is important is running this function in a post function of TextView to prevent performance issues as well as let the UiThread be free. So this code will run it on another thread. Besides, it will add the ability to expand TextView when you click on it:
const val MAX_LINES = 20
post {
setCaption(senderName, caption)
setOnClickListener {
let {
it.maxLines = MAX_LINES
it.text = getFullCaption(senderName, caption)
}
}
}I hope you find this article useful. You can read the code that I used this expandable TextView on Github.
