API Reference / Android Widgets / Highlighting
Apr. 24, 2019

Highlighting

About this widget

A great search interface highlights parts of the search results to explain why they are relevant to the user. With InstantSearch Android, the Highlightable interface and HighlightedString objects simplify highlighting the right words in a search response that match your query.
You can read more about the concept of highlighting in our highlighting guide.

Examples

Lets take the example of an index containing movies. Each movie record consists of two fields: title and year. Here is what the search engine response for a query "red" could look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    {
    "title": "The Shawshank Redemption",
    "year": 1994,
    "genre": ["action", "adventure"],
    "actors": ["Tim Robbins", "Morgan Freeman"],
    "objectID": "439817390",
    "_highlightResult": {
      "title": {
        "value": "The Shawshank <em>Red</em>emption",
        "matchLevel": "full",
        "fullyHighlighted": false,
        "matchedWords": [
          "red"
        ]
      },
    }
  },

To display those movies in your interface, you likely have created a data class that looks something like the following:

1
2
3
4
5
6
7
@Serializable
data class Movie(
    val title: String,
    val year: String,
    val genre: List<String>,
    override val objectID: ObjectID,
) : Indexable

Let’s update it to add some highlighting. Implementing Highlightable will deserialize the _highlightResult for each movie, and make it available through the getHighlight{s} methods. We can then create @Transient attributes for each highlight we want to display, being either single values or lists:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Serializable
data class Movie(
    val title: String,
    val year: String,
    val genre: List<String>,
    override val objectID: ObjectID
    override val _highlightResult: JsonObject?
) : Indexable, Highlightable {
  
  @Transient
  public val highlightedTitle: HighlightedString?
      get() = getHighlight(Attribute("title"))

  @Transient
  public val highlightedGenres: List<HighlightedString>?
      get() = getHighlights(Attribute("genre"))

  @Transient
  public val highlightedActors: List<HighlightedString>?
      get() = getHighlights(Attribute("actors"))
}

We can now use these highlighted strings in our interface, for example in a MovieViewHolder. There are three ways you can use a HighlightedString:

  • Directly as a SpannedString, with the highlight defaulting to bold:
    1
    
    TextUtils.concat(highlightedTitle?.toSpannedString(), " ($year)")
    
  • As a customized SpannedString, specifying a ParcelableSpan to use as highlight style:
    1
    2
    
     highlightedGenres?.toSpannedString(BackgroundColorSpan(Color.YELLOW))
         ?: buildSpannedString { italic { append("unknown genre") } }
    
  • Any way you want, iterating on HighlightedString#tokens to process it however you like:
    1
    2
    3
    4
    5
    6
    
     // Displays actors with highlighted parts in uppercase
     highlightedActors?.joinToString { highlight ->
            highlight.tokens.joinToString("") {
                if (it.highlighted) it.content.toUpperCase() else it.content
            }
        }
    

Did you find this page helpful?