Spot on: Android 14 adds highlights to TextViews
Tags: android
Published: 2023-03-10 13:56:11

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 `View`s. 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](https://developer.android.com/reference/android/text/Highlights) 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 `int`s.

`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](https://developer.android.com/reference/android/text/Highlights.Builder#Builder()) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u75lm1s3o13ofkq65b84.png)

```kotlin
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()
    }
  }
}
```

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

```kotlin
setSearchResultHighlights(1,3, 4, 6)
```

produces this output:


![a small screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bfsxcydw4mwnzfq3lalu.png)

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](https://github.com/tkuenneth/android-demos/tree/master/u/TextViewHighlightsDemo)