Android — replace the specific span of TextView with a drawable

nichiyoshi
2 min readMar 29, 2020

When you want to display text with icons as one TextView like below, how do you achieve it?

One simple approach is to constraint three components: TextView of “Press” and ImageView of camera drawable, and TaxtView of “please!!”.

But what happens when you need to support different languages with string resources, like below?

Japanese version

You may notice that the position of drawable depends on each language, so that aligning three views may make you struggle because you have to adjust the alignment according to each language.

Use SpannableString and ImageSpan

So what approach will be good in this case?

SpannableString and ImageSpan will be one of the solutions.

Span that replaces the text it’s attached to with a Drawable that can be aligned with the bottom or with the baseline of the surrounding text.

In this case, if you need two languages: Engish and Japanese, make string values like below.

// value/strings
<string name="explanation">Press cameraIcon please!!</string>
// value-ja/strings
<string name=”explanation”>cameraIconをタップしてね!</string>

The cameraIcon is the span that will be replaced with a drawable.

Below is the flow of replacing the word “cameraIcon” with a drawable.

To designate the span area, first, you need to get the start position of the span.

val string = resources.getString(R.string.explanation)
val spanText = "cameraIcon"
val startPosition = string.split(spanText)[0].length

Then, get the end position of the span.

val endPosition = startPosition + spanText.length

Finally, replace the span with a resource.

val ss = SpannableString(string)
val drawable = ContextCompat.getDrawable(this, R.drawable.ic_photo)

val lineHeight = textView.lineHeight
drawable!!.setBounds(0,0,lineHeight, lineHeight) // adjust the size of resource so that the resource fit with the sorrouncing text size.
ss.setSpan(ImageSpan(drawable), startPosition, endPosition, SPAN_EXCLUSIVE_EXCLUSIVE)

textView.text = ss

That’s all !!

After this, you do not have to care about using different languages as long as you use the mark text “cameraIcon”.

GitHub sample code is here.

--

--