API Reference / Android Widgets / Multi Hits
Apr. 24, 2019

Multi Hits

About this widget

Components that display a paginated list of search results from multiple indices.

To add MultiHits to your search experience, use these components:

  • SearcherMultipleIndex: The Searcher that handles your searches.
  • SearcherMultipleIndexDataSource: The PageKeyedDataSource that will load hits incrementally.
  • LivePagedListBuilder: The builder creating LiveData, based on the given DataSource and Config.
  • T, U, … : Data Classes representing each kind of search result.
  • FilterState: So the paginated list refreshes when filters change.

Examples

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
class MyActivity : AppCompatActivity() {

    val client = ClientSearch(
        ApplicationID("YourApplicationID"),
        APIKey("YourAPIKey")
    )
    val indexMovie = IndexQuery(IndexName("IndexMovie"))
    val indexActor = IndexQuery(IndexName("IndexActor"))
    val index = client.initIndex(IndexName("YourIndexName"))
    val searcher = SearcherMultipleIndex(client, listOf(indexMovie, indexActor))
    val pagedListConfig = PagedList.Config.Builder().setPageSize(10).build()
    val movieFactory = SearcherMultipleIndexDataSource.Factory(searcher, indexMovie) {
        it.deserialize(Movie.serializer())
    }
    val actorFactory = SearcherMultipleIndexDataSource.Factory(searcher, indexActor) {
        it.deserialize(Actor.serializer())
    }
    val movies = LivePagedListBuilder(movieFactory, pagedListConfig).build()
    val actors = LivePagedListBuilder(actorFactory, pagedListConfig).build()
    val adapterMovie = MovieAdapter()
    val adapterActor = ActorAdapter()
    val filterState = FilterState()
    val connection = ConnectionHandler()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        connection += filterState.connectPagedList(actors)
        connection += filterState.connectPagedList(movies)

        actors.observe(this, Observer { hits -> adapterActor.submitList(hits) })
        movies.observe(this, Observer { hits -> adapterMovie.submitList(hits) })

        searcher.searchAsync()
    }

    override fun onDestroy() {
        super.onDestroy()
        searcher.cancel()
        connection.disconnect()
    }
}

@Serializable
data class Movie(
    val title: String
)

@Serializable
data class Actor(
    val name: String
)

class MovieViewHolder(val view: TextView) : RecyclerView.ViewHolder(view) {

    fun bind(data: Movie) {
        view.text = data.title
    }
}

class ActorViewHolder(val view: TextView) : RecyclerView.ViewHolder(view) {

    fun bind(data: Actor) {
        view.text = data.name
    }
}

class ActorAdapter : PagedListAdapter<Actor, ActorViewHolder>(ActorAdapter) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ActorViewHolder {
        return ActorViewHolder(TextView(parent.context))
    }

    override fun onBindViewHolder(holder: ActorViewHolder, position: Int) {
        val actor = getItem(position)

        if (actor != null) {
            holder.bind(actor)
        }
    }

    companion object : DiffUtil.ItemCallback<Actor>() {

        override fun areItemsTheSame(
            oldItem: Actor,
            newItem: Actor
        ): Boolean {
            return oldItem == newItem
        }

        override fun areContentsTheSame(
            oldItem: Actor,
            newItem: Actor
        ): Boolean {
            return oldItem.name == newItem.name
        }
    }
}

class MovieAdapter : PagedListAdapter<Movie, MovieViewHolder>(MovieAdapter) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
        return MovieViewHolder(TextView(parent.context))
    }

    override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
        val movie = getItem(position)

        if (movie != null) holder.bind(movie)
    }

    companion object : DiffUtil.ItemCallback<Movie>() {

        override fun areItemsTheSame(
            oldItem: Movie,
            newItem: Movie
        ): Boolean {
            return oldItem == newItem
        }

        override fun areContentsTheSame(
            oldItem: Movie,
            newItem: Movie
        ): Boolean {
            return oldItem.title == newItem.title
        }
    }
}

Parameters

index
type: Integer
Required

Important: this is where you link your UI’s DataSource to the right search index.
The index of the associated IndexQuery in your SearcherMultipleIndex.

1
2
3
4
5
val indexMovie = IndexQuery(IndexName("IndexMovie"))
val indexActor = IndexQuery(IndexName("IndexActor"))

SearcherMultipleIndexDataSource.Factory(searcher, indexMovie) { /* ... */ }
SearcherMultipleIndexDataSource.Factory(searcher, indexActor) { /* ... */ }

Did you find this page helpful?