UI libraries / InstantSearch Android / Widgets
Signature
RelevantSortConnector(
  searcher: HitsSearcher,
  viewModel: RelevantSortViewModel
)

About this widget

Virtual indices allow you to 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 and can return less relevant results.

Examples

Instantiate a RelevantSortConnector and connect it to a RelevantSortView.

Android view

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
class MyActivity : AppCompatActivity() {
    val searcher = HitsSearcher(
        applicationID = ApplicationID("YourApplicationID"),
        apiKey = APIKey("YourSearchOnlyAPIKey"),
        indexName = IndexName("YourIndexName")
    )
    val relevantSort = RelevantSortConnector(searcher)
    val connection = ConnectionHandler(relevantSort)

    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)
        connection += relevantSort.connectView(view) { priority ->
            when (priority) {
                RelevantSortPriority.Relevancy -> RelevantSortText.Relevant
                RelevantSortPriority.HitsCount -> RelevantSortText.All
                else -> null // the index does not support Relevant sort
            }
        }
    }

    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")
}

Compose UI

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.

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
class MyActivity : AppCompatActivity() {
    val searcher = HitsSearcher(
        applicationID = ApplicationID("YourApplicationID"),
        apiKey = APIKey("YourSearchOnlyAPIKey"),
        indexName = 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()
    }
}

Parameters

searcher
type: HitsSearcher
Required

The Searcher that handles your searches.

viewModel
type: RelevantSortViewModel
default: RelevantSortViewModel()
Optional

The business logic handling the Relevant sort priority changes.

View

view
type: RelevantSortView<T>
Required

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?>.

presenter
type: RelevantSortPresenter<T>
Required

Presenter transforming the Relevant sort priority state to its representation for a view. Not required if you use RelevantSortPriorityView.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class RelevantSortBanner(val textView: TextView, val button: Button) : RelevantSortView<String> {
    init { button.setOnClickListener { didToggle?.invoke() } }
    override var didToggle: (() -> Unit)? = null
    override fun updateView(input: String) { this.textView.text = input }
}

val textView = TextView(this)
val button = Button(this)
val relevantSort = RelevantSortConnector(searcher)
val view = RelevantSortBanner(textView, button)

relevantSortConnector.connectView(view) { priority ->
    when (priority) {
        RelevantSortPriority.Relevancy -> "Showing only relevant results."
        else -> "Showing all results!"
    }
}

Low-level API

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.
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
class MyActivity : AppCompatActivity() {
    val searcher = HitsSearcher(
        applicationID = ApplicationID("YourApplicationID"),
        apiKey = APIKey("YourSearchOnlyAPIKey"),
        indexName = 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")
}
Did you find this page helpful?