Dynamic Facets
DynamicFacetListConnector( searcher: SearcherIndex, filterState: FilterState, orderedFacets: List<AttributedFacets>, selections: SelectionsPerAttribute, selectionModeForAttribute: Map<Attribute, SelectionMode>, filterGroupForAttribute: Map<Attribute, FilterGroupDescriptor> )
About this widget
DynamicFacetsListView
is a view that displays the ordered list of facets and facet values.
The order of groups and facet values in each group is defined by the corresponding settings of the index and may be altered by a Rule.
You can configure the facet merchandising through the corresponding index setting.
Learn how to set up ordering in the facet display guide.
Requirements
- You must set the
attributesForFaceting
and configure the facet order, either using the dashboard or usingattributesForFaceting
andrenderingContent
respectively with the API. - You must set the
facets
property of the query withSearcher.indexQueryState.query.facets
and provide the facet attributes you want to retrieve.
You must use at least InstantSearch Android version 2.11 to use Dynamic Facets.
Examples
Instantiate a DynamicFacetsListConnector
, set the query facets and launch an initial search on its searcher.
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
class MyActivity : AppCompatActivity() {
val searcher = HitsSearcher(
applicationID = ApplicationID("YourApplicationID"),
apiKey = APIKey("YourSearchOnlyAPIKey"),
indexName = IndexName("YourIndexName")
)
val filterState = FilterState()
val color = Attribute("color")
val country = Attribute("country")
val brand = Attribute("brand")
val size = Attribute("size")
val dynamicFacets = DynamicFacetListConnector(
searcher = searcher,
filterState = filterState,
selectionModeForAttribute = mapOf(
color to SelectionMode.Multiple,
country to SelectionMode.Multiple
),
filterGroupForAttribute = mapOf(
brand to (brand to FilterOperator.Or),
color to (color to FilterOperator.Or),
)
)
val connection = ConnectionHandler(dynamicFacets)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val dynamicFacetListView = DynamicFacetListAdapter(DynamicFacetListViewHolderImpl.Factory) // implementation of `DynamicFacetListView`
connection += dynamicFacets.connectView(dynamicFacetListView)
searcher.query.facets = setOf(brand, color, size, country)
searcher.searchAsync()
}
override fun onDestroy() {
super.onDestroy()
searcher.cancel()
connection.clear()
}
}
Parameters
searcher
|
type: SearcherIndex
Required
The |
filterState
|
type: FilterState
Required
The |
orderedFacets
|
type: List<AttributedFacets>
default: []
Optional
The ordered list of attributed facets. |
selections
|
type: SelectionsPerAttribute
default: []
Optional
The mapping between a facet attribute and a set of selected facet values. |
selectionModeForAttribute
|
type: Map<Attribute, SelectionMode>
default: [:]
Optional
The mapping between a facet attribute and a facet values selection mode. If not provided, the default selection mode is |
filterGroupForAttribute
|
type: Map<Attribute, FilterGroupDescriptor>
default: [:]
Optional
The mapping between a facet attribute and a descriptor of a filter group where the corresponding facet filters are stored in the filter state. |
View
view
|
type: DynamicFacetListView
Required
The view that render the dynamic facets list. |
||
Copy
|
Low-level API
If you want to fully control the DynamicFacetsList
components and connect them manually, you can use the following components:
Searcher
: theSearcher
that handles your searches.FilterState
: the current state of the filters.DynamicFacetsListViewModel
: dynamic facets business logic
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
class MyActivity : AppCompatActivity() {
val searcher = HitsSearcher(
applicationID = ApplicationID("YourApplicationID"),
apiKey = APIKey("YourSearchOnlyAPIKey"),
indexName = IndexName("YourIndexName")
)
val filterState = FilterState()
val color = Attribute("color")
val country = Attribute("country")
val brand = Attribute("brand")
val size = Attribute("size")
val dynamicFacetViewModel = DynamicFacetListViewModel(
selectionModeForAttribute = mapOf(
color to SelectionMode.Multiple,
country to SelectionMode.Multiple
)
)
val connection = ConnectionHandler(dynamicFacets)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
connection += dynamicFacetViewModel.connectSearcher(searcher)
connection += dynamicFacetViewModel.connectFilterState(filterState, mapOf(
brand to (brand to FilterOperator.Or),
color to (color to FilterOperator.Or))
)
val dynamicFacetListView = DynamicFacetListAdapter(DynamicFacetListViewHolderImpl.Factory) // implementation of `DynamicFacetListView`
connection += dynamicFacets.connectView(dynamicFacetListView)
searcher.query.facets = setOf(brand, color, size, country)
searcher.searchAsync()
}
override fun onDestroy() {
super.onDestroy()
searcher.cancel()
connection.clear()
}
}
Customizing your view
InstantSearch Android provides DynamicFacetListView
interface, it’s the view presenting the ordered list of facets and handling user interaction.
You can provide your implementation of DynamicFacetListView
interface:
1
2
val myDynamicFacetListView = MyDynamicFacetListView() // your implementation `DynamicFacetListView`
dynamicFacets.connectView(myDynamicFacetListView)
Android view
InstantSearch Android provides DynamicFacetListAdapter
, an opinionated implementation of DynamicFacetListView
interface and a subclass of ListAdapter
class.
Provide your implementation of DynamicFacetListViewHolder.Factory
interface to your DynamicFacetListAdapter
:
1
2
3
val factory = DynamicFacetListViewHolderImpl.Factory // your implementation of `DynamicFacetListViewHolder.Factory`
val dynamicFacetListView = DynamicFacetListAdapter(factory)
dynamicFacets.connectView(dynamicFacetListView)
Compose UI
InstantSearch Android provides the DynamicFacetListState
, an implementation of the DynamicFacetListView
interface adapted for usage with Compose UI.
It provides facetOrder
and facetSelections
properties with convenient toggle
and isSelected
functions which allow you to implement your own Compose UI view.
Implementation example
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
@Composable
fun DynamicFacetsList(modifier: Modifier = Modifier, dynamicFacetListState: DynamicFacetListState) {
LazyColumn(modifier) {
dynamicFacetListState.facetOrder.forEach { (attribute, facets) ->
item {
Header(attribute = attribute)
}
items(facets) { facet ->
FacetRow(
modifier = Modifier.fillMaxWidth(),
facet = facet,
isSelected = dynamicFacetListState.isSelected(facet, attribute),
onClick = { dynamicFacetListState.toggle(facet, attribute) }
)
}
}
}
}
@Composable
fun Header(modifier: Modifier = Modifier, attribute: Attribute) {
Text(modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp), text = attribute.raw)
}
@Composable
fun FacetRow(modifier: Modifier = Modifier, facet: Facet, isSelected: Boolean,onClick: () -> Unit = {}) {
Card(modifier = modifier, onClick = onClick) {
Row(Modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
Text(modifier = Modifier.weight(1f), text = facet.value)
if (isSelected) Icon(Icons.Default.Check, contentDescription = null)
Text(text = facet.count.toString())
}
}
}