Guides / Building Search UI / Ecommerce ui template / Components / Product listing page filter and nav / Filters refinements

The Flutter Helpers are available as alpha software. They depend on the Algolia Dart API client, which is developed by the community. Note that the Algolia SLA don’t apply to community projects. To share feedback or report a bug, open an issue.

The Filters and refinements components allow users to filter results from a drawer. The drawer can be shown or hidden.

Filters & Sort button

Filters and sort

The FiltersScreen component provides a way to filter the results. Each filter is displayed in an silver list. You can show or hide the filters.

Filters & Sort drawer

Code summary

To customize the FiltersScreen component, edit the filters_screen.dart file.

Usage and props

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
class FiltersScreen extends StatefulWidget {
  const FiltersScreen({super.key});

  @override
  State<FiltersScreen> createState() => _FiltersScreenState();
}

enum FiltersSection { none, sort, brand, size }

class _FiltersScreenState extends State<FiltersScreen> {
  FiltersSection activeSection = FiltersSection.none;

  bool _isActive(FiltersSection section) => section == activeSection;

  @override
  Widget build(BuildContext context) {
    final searchRepository = context.read<SearchRepository>();
    return Padding(
        padding: EdgeInsets.only(
            top: MediaQuery.of(context).padding.top,
            bottom: MediaQuery.of(context).padding.bottom,
            left: 10,
            right: 10),
        child: Column(
          children: [
            const FiltersHeaderView(),
            const SizedBox(
              height: 10,
            ),
            Expanded(
              child: CustomScrollView(
                slivers: [
                  _sortHeader(searchRepository.selectedIndex),
                  if (_isActive(FiltersSection.sort))
                    SortSelectorView(
                      sorts: searchRepository.selectedIndex,
                      onToggle: searchRepository.selectIndexName,
                    ),
                  _brandHeader(),
                  if (_isActive(FiltersSection.brand))
                    BrandSelectorView(
                      facets: searchRepository.brandFacets,
                      onToggle: searchRepository.toggleBrand,
                    ),
                  _sizeHeader(),
                  if (_isActive(FiltersSection.size))
                    SizeSelectorView(
                      facets: searchRepository.sizeFacets,
                      onToggle: searchRepository.toggleSize,
                    ),
                ],
              ),
            ),
            const Divider(),
            FiltersFooterView(
              metadata: searchRepository.searchMetadata,
              onClear: searchRepository.clearFilters,
            ),
          ],
        ));
  }

  Widget _sortHeader(Stream<SortIndex> sorts) {
    const section = FiltersSection.sort;
    final isActive = _isActive(section);
    return ExpandableHeaderView(
      title: SortTitleView(
        sorts: sorts,
        isActive: isActive,
      ),
      isActive: isActive,
      onToggle: () => _toggleSection(section),
    );
  }

  Widget _brandHeader() {
    const section = FiltersSection.brand;
    return ExpandableHeaderView(
      title: const Text('Brand',
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)),
      isActive: _isActive(section),
      onToggle: () => _toggleSection(section),
    );
  }

  Widget _sizeHeader() {
    const section = FiltersSection.size;
    return ExpandableHeaderView(
      title: const Text('Size',
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)),
      isActive: _isActive(section),
      onToggle: () => _toggleSection(section),
    );
  }

  _toggleSection(FiltersSection section) => setState(
      () => activeSection = _isActive(section) ? FiltersSection.none : section);
}

Components

FilterScreen uses the following components:

Component Description
Facets Filter product results with facets
Sort Sort products according to different criteria
Did you find this page helpful?