0

I´d like to use icons in the text of a TextView. (Not in front or in the end of it.) The basic idea is a short infobox, telling the user, that these fancy three lines up there are the menu. (Since it is not possible to write "Menu" below them, except I want to handle all the click events myself too. sigh) So my text should be something like this: icon in text

Right now this is just an icon added at the end of the textview, but as you can clearly see, it looks very ugly, and only works with a fixed screen-size. In landscape mode the icon would be at the completely other side of the screen, than the text. Therefore I am searching for some way to write icons inside of the text. I was thinking about something like "Um das Menü zu öffnen, tippe auf @drawable/sandwich" in the string resources or similar. (Which obviously doesn´t work like that, sadly.)

Is this possible? Or, if not, is there maybe some secret trick to add a text to the sandwich icon in the action bar at the top, without creating my custom layout? Around 50% of my users have issues realizing it is a menu, since they are not used to a lot of apps.

2 Answers2

1

Yes, you can do it using SpannableString. See the below example:

val modifiedText = "your-text-here %icon%" // you can use resource string here
val span = SpannableString(modifiedText)
val drawable = ResourcesCompat.getDrawable(resources, R.drawable.your_image, null)
drawable?.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
val image = ImageSpan(drawable, ImageSpan.BOTTOM)
val startIndex = modifiedText.indexOf("%icon%")

//Replace %icon% with drawable
span.setSpan(image, startIndex, startIndex + 6, Spannable.SPAN_INCLUSIVE_INCLUSIVE)
yourTextView.setText(span)
Alpha 1
  • 4,118
  • 2
  • 17
  • 23
0

You could use VerticalImageSpan which is an extension to ImageSpan.

And use the following TextView extension function takes in the index in the TextView that you want to place the drawable in; a drawable, the desired image width & height.

fun TextView.addDrawableAt(index: Int, @DrawableRes imgSrc: Int, imgWidth: Int, imgHeight: Int) {
    val ssb = SpannableStringBuilder(this.text)

    val drawable = ContextCompat.getDrawable(this.context, imgSrc) ?: return
    drawable.mutate()
    drawable.setBounds(
        0, 0,
        imgWidth,
        imgHeight
    )
    ssb.setSpan(
        VerticalImageSpan(drawable),
        index - 1,
        index,
        Spannable.SPAN_INCLUSIVE_EXCLUSIVE
    )
    this.setText(ssb, TextView.BufferType.SPANNABLE)
}
Zain
  • 37,492
  • 7
  • 60
  • 84