DEV Community

Cover image for Spot on: Android 14 adds highlights to TextViews
Thomas Künneth
Thomas Künneth

Posted on

Spot on: Android 14 adds highlights to TextViews

Given that Google wants us to use Jetpack Compose for our app user interfaces, it may come as a surprise that Mountain View is still adding functionality to classic Views. Yet, countless apps are using XML-based layouts and this may not change on a large scale soon, so why not enhance their experience? Android 14 will add a bunch of new methods to TextViev (and classes extending it) which allow us to set and query highlights.

So, what's a highlight?

android.text.Highlights extends Object. Currently the documentation says:

A class that represents of the highlight of the text.

getPaint(int i) returns a paint used for the i-th highlight.

So, there can be more than one highlight.

getRanges(int i) returns the ranges of the i-th highlight.

The ranges are represented by an array of ints.

getSize() returns the number of highlights.

Why don't they just call it getNumberOfHighlights()?

So, do you already feel en-light-ed? Me neither. Let's continue.

android.text.Highlights.Builder is

A builder for the Highlights.

There's just a parameter-less constructor and two methods that configure the builder.

  1. addRange(Paint paint, int start, int end)
  2. addRanges(Paint paint, int... ranges)

In both cases, a paint object is passed. It will be used for drawing the highlights.

addRange() adds one range from start (included) to end (not included). addRanges(), well, adds several ranges.

Not to much surprise, build() returns a Highlights instance.

Next, let's take a look how to make use of all this.

Screenshot of the app TextViewHighlightsDemo

package eu.thomaskuenneth.textviewhighlightsdemo

import android.graphics.Color
import android.graphics.Paint
import android.os.Bundle
import android.text.Highlights
import androidx.appcompat.app.AppCompatActivity
import eu.thomaskuenneth.textviewhighlightsdemo.databinding.MainBinding

private const val TEXT = "*ABCD*"

class MainActivity : AppCompatActivity() {

  private lateinit var binding: MainBinding

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = MainBinding.inflate(layoutInflater)
    setContentView(binding.root)
    val greenPaint = Paint().apply {
      color = Color.GREEN
    }
    val redPaint = Paint().apply {
      color = Color.RED
    }
    with(binding.textview1) {
      text = TEXT
      val builder = Highlights.Builder()
        .addRange(greenPaint, 1, 3)
        .addRange(redPaint, 3, 5)
      highlights = builder.build()
    }
    with(binding.textview2) {
      text = TEXT
      val builder = Highlights.Builder()
        .addRanges(redPaint, 0, 1, 3, 5)
      highlights = builder.build()
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

So, use addRanges() to highlight several portions of a text with the same paint, but chain addRange() invocations to use different colors.

There is a new TextView method called setSearchResultHighlights(). Invoking it like this on my example

setSearchResultHighlights(1,3, 4, 6)
Enter fullscreen mode Exit fullscreen mode

produces this output:

a small screenshot

You can set the search result highlight color using setSearchResultHighlightColor().

Unless I missed something, this new feature has not been mentioned to great extent. So if this is part of something big or just a small enhancement remains to be seen. I hope you enjoyed this look under the hood. Please share your thoughts in the comments.


Source code

Top comments (1)

Collapse
 
zubarevtututech profile image
zubarevTutuTech

Hi!

How does this differ from BackgroundColorSpan ?