FilterListConnector.All(
filters: List<Filter>,
filterState: FilterState,
selectionMode: SelectionMode,
groupID: FilterGroupID
)
FilterList
is a filtering view that displays any kind of filters,
and lets users refine the search results by selecting them.
Compared to the RefinementList
,
which takes its values from the search response facets,
this widget displays filters that you add yourself.
Examples
class MyActivity: AppCompatActivity() {
val searcher = HitsSearcher(
applicationID = ApplicationID("YourApplicationID"),
apiKey = APIKey("YourSearchOnlyAPIKey"),
indexName = IndexName("YourIndexName")
)
val filterState = FilterState()
val color = Attribute("color")
val price = Attribute("price")
val filters = listOf(
Filter.Numeric(price, 5..10),
Filter.Tag("coupon"),
Filter.Facet(color, "red"),
Filter.Facet(color, "black"),
Filter.Numeric(price, NumericOperator.Greater, 100)
)
val groupAll = groupAnd(all)
val filterListConnector = FilterListConnector.All(
filters = filters,
filterState = filterState,
groupID = groupAll
)
val connection = ConnectionHandler(filterListConnector, searcher.connectFilterState(filterState))
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val filterListView: FilterListView.All = MyFilterListAdapter() // your `FilterListView.All` implementation
connection += filterListConnector.connectView(filterListView)
searcher.searchAsync()
}
override fun onDestroy() {
super.onDestroy()
connection.disconnect()
searcher.cancel()
}
}
Low-level API
If you want to fully control the FilterList
components and connect them manually, use the following components:
Searcher
. The Searcher
that handles your searches.
FilterState
. The current state of the filters.
FilterListViewModel.All
. The logic applied to the filters.
FilterListView.All
. The view that renders the filters.
FilterPresenter
. Optional. The presenter to customize the display of the filters.
class MyActivity : AppCompatActivity() {
val searcher = HitsSearcher(
applicationID = ApplicationID("YourApplicationID"),
apiKey = APIKey("YourSearchOnlyAPIKey"),
indexName = IndexName("YourIndexName")
)
val filterState = FilterState()
val color = Attribute("color")
val price = Attribute("price")
val filters = listOf(
Filter.Numeric(price, 5..10),
Filter.Tag("coupon"),
Filter.Facet(color, "red"),
Filter.Facet(color, "black"),
Filter.Numeric(price, NumericOperator.Greater, 100)
)
val viewModel = FilterListViewModel.All(filters)
val connection = ConnectionHandler()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val view: FilterListView.All = MyFilterListAdapter() // your `FilterListView.All` implementation
connection += searcher.connectFilterState(filterState)
connection += viewModel.connectFilterState(filterState)
connection += viewModel.connectView(view)
searcher.searchAsync()
}
override fun onDestroy() {
super.onDestroy()
connection.disconnect()
searcher.cancel()
}
}
Compose UI
InstantSearch provides the FilterListState
as a state model,
which is an implementation of the FilterListView
interface.
You need to connect FilterListState
to the FilterListConnector
or FilterListViewModel
like any other FilterListView
implementation.
class MyActivity: AppCompatActivity() {
val searcher = HitsSearcher(
applicationID = ApplicationID("YourApplicationID"),
apiKey = APIKey("YourSearchOnlyAPIKey"),
indexName = IndexName("YourIndexName")
)
val filterState = FilterState()
val color = Attribute("color")
val price = Attribute("price")
val filters = listOf(
Filter.Numeric(price, 5..10),
Filter.Tag("coupon"),
Filter.Facet(color, "red"),
Filter.Facet(color, "black"),
Filter.Numeric(price, NumericOperator.Greater, 100)
)
val groupAll = groupAnd(all)
val filterListState = FilterListState<Filter>()
val filterList = FilterListConnector.All(
filters = filters,
filterState = filterState,
groupID = groupAll
)
val connections = ConnectionHandler(filterList)
init {
connections += searcher.connectFilterState(filterState)
connections += filterList.connectView(filterListState)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
filterListState.items.forEach { selectableFacet ->
FilterRow( // your own UI composable to display `SelectableItem<Filter>`
selectableFilter = selectableFacet,
onClick = { filterListState.onSelection?.invoke(it) }
)
}
}
searcher.searchAsync()
}
override fun onDestroy() {
super.onDestroy()
connections.disconnect()
searcher.cancel()
}
}
Parameters
selectionMode
SelectionMode
default: Multiple
Whether the list can have Single
or Multiple
selections.
groupID
FilterGroupID
default: FilterGroupID(FilterOperator.And)
The identifier for the group of filters.
View
The view that renders the filters.val view: FilterListView.All = MyFilterListAdapter()
filterListConnector.connectView(view)
// Example of FilterListView.All implementation
class MyFilterListAdapter : FilterListView.All,
ListAdapter<SelectableItem<Filter>, FilterListViewHolder>(DiffUtilItem()) {
override var onSelection: Callback<Filter>? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FilterListViewHolder {
return FilterListViewHolder(parent.inflate(R.layout.list_item_selectable))
}
override fun onBindViewHolder(holder: FilterListViewHolder, position: Int) {
val (filter, selected) = getItem(position)
holder.bind(FilterPresenterImpl()(filter), selected) { onSelection?.invoke(filter) }
}
override fun setItems(items: List<SelectableItem<Filter>>) {
submitList(items)
}
}
class DiffUtilItem<T : Filter> : DiffUtil.ItemCallback<SelectableItem<T>>() {
override fun areItemsTheSame(oldItem: SelectableItem<T>, newItem: SelectableItem<T>): Boolean {
return oldItem.first == newItem.first
}
override fun areContentsTheSame(oldItem: SelectableItem<T>, newItem: SelectableItem<T>): Boolean {
return oldItem == newItem
}
}