Guides / Building Search UI / UI & UX patterns

Algolia Places for InstantSearch Android

Places is going away on May 31, 2022. Read the announcement.

Using Places on Android

You can use Algolia Places on Android by using SearcherPlaces.

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
Create a `RecyclerView.Adapter` and `ViewHolder` to display the results in a list:


```kotlin
class PlacesViewHolder(val view: View) : RecyclerView.ViewHolder(view) {

    fun bind(place: PlaceLanguage) {
        println(place.highlightResultOrNull)
        val name = place.highlightResultOrNull
            ?.toHighlights("locale_names")
            ?.firstOrNull()
            ?.tokenize() ?: place.localNames.first()
        val county = place.highlightResultOrNull
            ?.toHighlights("county")
            ?.firstOrNull()
            ?.tokenize() ?: place.county.first()
        val postCode = place.postCodeOrNull?.firstOrNull()?.let { ", $it" } ?: ""

        view.placeName.text = TextUtils.concat(name, ", ", county, postCode)
    }

    fun HighlightResult.tokenize(): SpannedString {
        return HighlightTokenizer()(value).toSpannedString()
    }
}

class PlacesAdapter : ListAdapter<PlaceLanguage, PlacesViewHolder>(PlacesAdapter), HitsView<PlaceLanguage> {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlacesViewHolder {
        return PlacesViewHolder(parent.inflate(R.layout.place_item))
    }

    override fun onBindViewHolder(holder: PlacesViewHolder, position: Int) {
        val item = getItem(position)

        if (item != null) holder.bind(item)
    }

    override fun setHits(hits: List<PlaceLanguage>) {
        submitList(hits)
    }

    companion object : DiffUtil.ItemCallback<PlaceLanguage>() {

        override fun areItemsTheSame(oldItem: PlaceLanguage, newItem: PlaceLanguage): Boolean {
            return oldItem.objectIDOrNull == newItem.objectIDOrNull
        }

        override fun areContentsTheSame(oldItem: PlaceLanguage, newItem: PlaceLanguage): Boolean {
            return oldItem == newItem
        }
    }
}

Finally, create your activity with a SearchView and a RecyclerView to provide a search autocomplete experience:

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
class PlacesActivity : AppCompatActivity() {

    val query = PlacesQuery(
        type = PlaceType.City,
        hitsPerPage = 10,
        aroundLatLngViaIP = false,
        countries = listOf(Country.France)
    )
    val searcher = SearcherPlaces(query = query, language = Language.English)
    val searchBox = SearchBoxConnector(searcher)
    val adapter = PlacesAdapter()
    val connection = ConnectionHandler(searchBox)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.places_activity)

        connection += searchBox.connectView(SearchBoxViewAppCompat(searchView))
        connection += searcher.connectHitsView(adapter) { hits -> hits.hits }

        placesList.let {
            it.itemAnimator = null
            it.adapter = adapter
            it.layoutManager = LinearLayoutManager(this)
            it.autoScrollToStart(adapter)
        }

        searcher.searchAsync()
    }

    override fun onDestroy() {
        super.onDestroy()
        connection.disconnect()
    }
}
Did you find this page helpful?