Search code examples
androidsearchsearchviewsearchable

Implementing (network) search android


I'm lost.

For the last few days, I'm trying to understand what will be the best way to implement a network search in my Android app.

I would like to keep the MVVM architecture but if it's too much to ask, I'm ready to consider the alternatives.

I need to be able to search in pages.

A good example\guide will be very appreciated.

Thanks.


Solution

  • Using Android's Paging Library, you can accomplish a paged network search, and update a RecyclerView with your results.

    Let's assume you have an API which we can use to invoke a search query. This would be backed by a DataSource you would implement, which would provide new pages of results as you scroll.

    interface MySearchApi {
        fun search(query: String, count: Int): PagedList<SearchResult>
    }
    

    What we get back is a PagedList, which is updated as more search results are loaded. We aren't wrapping this in an Rx Observable or a LiveData object, because in this case we don't expect loaded data to change. If you were querying some kind of real time service which could have results change at any time, you might want to consider that.

    We can publicize this paged list or LiveData from our ViewModel object, and build a PagedListAdapter subclass which will update a RecyclerView with the new data as it is loaded.

    class MySearchAdapter() :
            PagedListAdapter<SearchResult, SearchResultViewHolder>(DIFF_CALLBACK) {
        fun onBindViewHolder(holder: SearchResultViewHolder, position: Int) {
            val concert: SearchResult? = getItem(position)
    
            // Note that "searchResult" is a placeholder if it's null.
            holder.bindTo(searchResult)
        }
    
        companion object {
            private val DIFF_CALLBACK = object :
                    DiffUtil.ItemCallback<Concert>() {
                // Concert details may have changed if reloaded from the database,
                // but ID is fixed.
                override fun areItemsTheSame(oldSearchResult: SearchResult,
                        newSearchResult: SearchResult) = oldSearchResult.id == newSearchResult.id
    
                override fun areContentsTheSame(oldSearchResult: SearchResult,
                        newSearchResult: Concert) = newSearchResult == newSearchResult
            }
        }
    }
    
    

    Wiring this up with a RecyclerView is done as you normally would any other Adapter and RecyclerView, and your PagedList should be notifying your DataSource whenever it requires a new page of data.

    You can read more about the Pagination Architecture here.