About this widget
To use this widget to display a paginated list of results from multiple categories, you need these components:MultiSearcher. TheSearcherthat handles your searchesFilterState. Tracks any applied filters (such as genre or year) and updates search results when the filters change.HitsState. Hits UI stateSearchBoxState. Search box UI state
Examples
Activity
Kotlin
Report incorrect code
Copy
class SearchActivity : ComponentActivity() {
private val viewModel: SearchViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
SearchScreen(
searchBoxState = viewModel.searchBoxState,
actorsState = viewModel.actorsState,
moviesState = viewModel.moviesState,
)
}
}
}
}
View model
Kotlin
Report incorrect code
Copy
class SearchViewModel : ViewModel() {
private val multiSearcher = MultiSearcher(
applicationID = ApplicationID("YourApplicationID"),
apiKey = APIKey("YourAPIKey")
)
private val actorsSearcher = multiSearcher.addHitsSearcher(IndexName("YourActorsIndex"), Query(hitsPerPage = 5))
private val moviesSearcher = multiSearcher.addHitsSearcher(IndexName("YourMoviesIndex"))
private val searchBoxConnector = SearchBoxConnector(multiSearcher)
private val connections = ConnectionHandler(searchBoxConnector)
val searchBoxState = SearchBoxState()
val actorsState = HitsState<Actor>()
val moviesState = HitsState<Movie>()
init {
connections += searchBoxConnector.connectView(searchBoxState)
connections += actorsSearcher.connectHitsView(actorsState) { it.hits.deserialize(Actor.serializer()) }
connections += moviesSearcher.connectHitsView(moviesState) { it.hits.deserialize(Movie.serializer()) }
multiSearcher.searchAsync()
}
override fun onCleared() {
super.onCleared()
multiSearcher.cancel()
connections.clear()
}
}
UI
Kotlin
Report incorrect code
Copy
@Composable
fun SearchScreen(
modifier: Modifier = Modifier,
searchBoxState: SearchBoxState,
actorsState: HitsState<Actor>,
moviesState: HitsState<Movie>,
) {
val scrollState = rememberScrollState()
Column(
modifier = modifier
.fillMaxWidth()
.verticalScroll(scrollState)
) {
SearchBox(
modifier = Modifier
.fillMaxWidth()
.padding(12.dp),
searchBoxState = searchBoxState,
)
Actors(actors = actorsState.hits)
Movies(movies = moviesState.hits)
}
}
@Composable
private fun Actors(
modifier: Modifier = Modifier,
actors: List<Actor>,
) {
if (actors.isEmpty()) return
Column(modifier) {
SectionTitle(
modifier = Modifier.padding(start = 12.dp, end = 12.dp, bottom = 4.dp),
title = "Actors"
)
actors.forEach { actor ->
Actor(actor = actor)
}
}
}
@Composable
private fun Actor(
modifier: Modifier = Modifier,
actor: Actor
) {
Row(
modifier
.fillMaxWidth()
.background(MaterialTheme.colors.surface)
.padding(horizontal = 24.dp, vertical = 12.dp)
) {
Icon(
imageVector = Icons.Default.AccountCircle,
tint = MaterialTheme.colors.onSurface.copy(alpha = 0.2f),
contentDescription = null
)
Text(
text = actor.highlightedName?.toAnnotatedString() ?: AnnotatedString(actor.name),
modifier = Modifier.padding(start = 12.dp),
)
}
}
@Composable
private fun Movies(
modifier: Modifier = Modifier,
movies: List<Movie>
) {
if (movies.isEmpty()) return
Column(modifier) {
SectionTitle(
modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp),
title = "Movies"
)
movies.forEach { movie ->
Movie(movie = movie)
}
}
}
@Composable
private fun Movie(modifier: Modifier = Modifier, movie: Movie) {
Row(
modifier
.fillMaxWidth()
.background(MaterialTheme.colors.surface)
.padding(horizontal = 24.dp, vertical = 12.dp)
) {
Icon(
imageVector = Icons.Default.Movie,
tint = MaterialTheme.colors.onSurface.copy(alpha = 0.2f),
contentDescription = null
)
Text(
text = movie.highlightedTitle?.toAnnotatedString() ?: AnnotatedString(movie.title),
modifier = Modifier.padding(start = 12.dp),
)
}
}
@Composable
private fun SectionTitle(modifier: Modifier = Modifier, title: String) {
Text(
modifier = modifier,
text = title, style = MaterialTheme.typography.subtitle2,
color = MaterialTheme.colors.onBackground.copy(alpha = 0.4f),
)
}
Models
Kotlin
Report incorrect code
Copy
@Serializable
data class Actor(
val name: String,
override val objectID: ObjectID,
override val _highlightResult: JsonObject?
) : Indexable, Highlightable {
val highlightedName
get() = getHighlight(Attribute("name"))
}
Kotlin
Report incorrect code
Copy
@Serializable
data class Movie(
val title: String,
override val objectID: ObjectID,
override val _highlightResult: JsonObject?
) : Indexable, Highlightable {
val highlightedTitle
get() = getHighlight(Attribute("title"))
}