Skip to content

5.x | Search Filter

Davide Steduto edited this page Jul 23, 2016 · 28 revisions

In this page

  • Introduction
  • Configuration
  • Special behaviors on action
  • Performance result
  • Example: Setup the SearchView
  • 3rd libraries and floating SearchView

Introduction

To collect items based on the searchText, the item must implement the interface IFilterable or it will be simply skipped. The searchText will be propagated to the custom implementation of the filter() method.

Important note: PASS ALWAYS A COPY OF THE ORIGINAL LIST: due to internal mechanism, items are removed and/or added in order to animate items in the final list.

Items that implement IExpandable interface with a non-empty sub list of children items, will be automatically scanned by the Adapter and sub items picked up if searchText has a match. Also the IExpandable items are automatically picked up and displayed if at least a child is collected by the current filter.

If you don't want to implement the IFilterable interface on the items, then, you can override the method filterObject(item, constraint) to have another filter logic!

Configuration

setAnimateToLimit(n_of_items)

Animation during filtering will be performed if the total items are below the limit of 600 (default) "current items" OR "filtered items"; Above this limit, notifyDataSetChanged() will be called anyway(!) with no animation.

setNotifyChangeOfUnfilteredItems(notifyChange)

To be continued

setNotifyMoveOfFilteredItems(notifyMove)

To be continued

setSearchText(), getSearchText(), hasSearchText(), hasNewSearchText()

To be continued

filterItems(unfilteredItems) or filterItems(unfilteredItems, long delay) ?

To be continued

Under the hood

A queue of notifications are executed in onPostExecute().
Also using the LinkedHashSet instead of List made a big improvement itself.

Special behaviors on action

  • From beta8, the filter is 100% asynchronous, it uses the internal AsyncTask supporting a very high-volume of items.
  • Sticky Header is disabled during the filter operation and restored when searchText returns empty.
  • If search text is empty or null, the provided list is the current list.
  • When sub items are collected, headers/parents are displayed too.
  • You should disable the refresh and the addition of the items.
  • If search text is empty or null, the provided list is the current list.
  • Restoring deleted items with Undo functionality enabled:
    • Deleting items before the filter starts, restoring them while the filter is active, it makes the restored items to be displayed if part of the current filtered collection and at the correct position.
    • Starting the filter and removing items, then restoring them with no filter active, it makes the restored items to be displayed at the correct position too.
  • Expandable item will collapse/expand only the filtered sub items.
  • Screen rotation is also supported but, the search will be performed again. To be continued

Performance result (when animations are active)

Tested with 💯000 items in the emulator:

10:58:02.225 5003-5003/D/MainActivity: onQueryTextChange newText: 7
10:58:02.435 5003-5098/I/FilterAsyncTask: doInBackground - started Filter
10:58:02.435 5003-5098/V/FlexibleAdapter: FilterItems with searchText=7
10:58:03.535 5003-5098/V/FlexibleAdapter: Animate changes! oldSize=100001 newSize=40951
10:58:04.917 5003-5098/V/FlexibleAdapter: calculateRemovals total out=59050
10:58:04.940 5003-5098/V/FlexibleAdapter: calculateAdditions total new=0
10:58:04.940 5003-5098/I/FilterAsyncTask: doInBackground - ended Filter
10:58:04.946 5003-5003/V/FlexibleAdapter: Performing 100001 notifications
10:58:05.401 5003-5003/D/MainActivity: onUpdateEmptyView size=40951

From the moment the background process starts it taks ~2.5s + ~0.5s to perform remove/insert notifications.

You can play with the FragmentAsyncFilter to familiarize with the options for the filter.

Example: Setup the SearchView (code snipped from the demoApp)

To be continued

3rd libraries and floating SearchView

List of libraries that can work with FlexibleAdapter.
To be continued

Clone this wiki locally