Virtual indices let you use relevant sort,
a sorting mechanism that favors relevancy over the attribute you’re sorting on.
The relevantSort widget displays the current search mode when searching in a virtual replica index,
and allows users to switch between relevant and regular sorting,
which is more exhaustive but can return less relevant results.
InstantSearch provides the RelevantSortState as a state model, which is an implementation of the RelevantSortView interface.
RelevantSortState must be connected to the RelevantSortConnector or RelevantSortViewModel like any other RelevantSortView implementation.
Kotlin
class MyActivity : AppCompatActivity() { val searcher = HitsSearcher( applicationID = "YourApplicationID", apiKey = "YourSearchOnlyAPIKey", indexName = "YourIndexName" ) val relevantSortState = RelevantSortState<String?>(null) val relevantSort = RelevantSortConnector(searcher) val connections = ConnectionHandler(relevantSort) init { connections += relevantSort.connectView(relevantSortState) { priority -> when (priority) { RelevantSortPriority.Relevancy -> "We removed some search results to show you the most relevant ones" RelevantSortPriority.HitsCount -> "Currently showing all results" else -> null // the index does not support Relevant sort } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MyRelevantSortBanner(relevantSortState) // your own UI composable to display relevant sort banner } } override fun onDestroy() { super.onDestroy() connections.disconnect() searcher.cancel() }}
The view that presents and toggles the relevant sort priority state.
If you don’t need to transform anything,
you can use RelevantSortPriorityView instead,
which is a type alias of RelevantSortView<RelevantSortPriority?>.
If you want to fully control the RelevantSort components and connect them manually, you can use the following components:
Searcher. The Searcher that handles your searches.
RelevantSortViewModel. The business logic handling the Relevant sort priority changes.
RelevantSortView<T>. The view that presents and toggles the Relevant sort priority state. RelevantSortPriorityView is a type alias of RelevantSortView<RelevantSortPriority?>.
RelevantSortPresenter<T>. Generic presenter transforming the Relevant sort priority state to its representation for a view. Optional if you use RelevantSortPriorityView.
Kotlin
class MyActivity : AppCompatActivity() { val searcher = HitsSearcher( applicationID = "YourApplicationID", apiKey = "YourSearchOnlyAPIKey", indexName = "YourIndexName" ) val connection = ConnectionHandler() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val banner = findViewById<View>(R.id.banner) val button = findViewById<Button>(R.id.buttonBanner) val textView = findViewById<TextView>(R.id.labelBanner) val view = RelevantSortBanner(banner, button, textView) val viewModel = RelevantSortViewModel() connection += viewModel.connectSearcher(searcher) connection += viewModel.connectView(view) { priority -> when (priority) { RelevantSortPriority.Relevancy -> RelevantSortText.Relevant RelevantSortPriority.HitsCount -> RelevantSortText.All else -> null } } } override fun onDestroy() { super.onDestroy() connection.disconnect() searcher.cancel() }}class RelevantSortBanner(val banner: View, val button: Button, val textView: TextView) : RelevantSortView<RelevantSortText?> { init { button.setOnClickListener { didToggle?.invoke() } } override var didToggle: (() -> Unit)? = null override fun updateView(input: RelevantSortText?) { when (input) { null -> banner.visibility = View.GONE else -> { banner.visibility = View.VISIBLE button.text = input.buttonText textView.text = input.label } } }}enum class RelevantSortText(val buttonText: String, val label: String) { Relevant("Show all results", "We removed some search results to show you the most relevant ones"), All("Show more relevant results", "Currently showing all results")}