Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Euan T
Euan T

Posted on • Originally published ateuantorano.co.uk on

     

Searching Paged Data In Jetpack Compose

I've recently created a new Android app using theJetpack Compose UI App Development Toolkit which consisted of a list of items which needed to be searchable. As the list was quite long, and the API I was talking to implemented support for pagination, I made use of thePaging library to lazy load items into the list as it scrolled.

Nice and easy so far. Now came the time to implement searching for items. I wanted to be able to toggle a search box at the top of the page and have the list of items filter itself based upon the search term as the user typed. After a little trial and error and a good while searching through Google's documentation given how rarely I work with Android, I came up with a nice and simple solution.

The end result that we're aiming for is something like this:

A demo of the search in action searching for products that match the search term 'Phone' within a sample application.

My ViewModel layers all useKotlin Flows to store state, meaning my basic view model for the paged data looked something like the following:

@HiltViewModelclassProductListViewModel@Injectconstructor(privatevalrepository:Repository):ViewModel(){valproducts=Pager(PagingConfig(pageSize=10,enablePlaceholders=false,)){ProductPagingSource(repository=repository,search=query,)}.flow.cachedIn(viewModelScope)}
Enter fullscreen modeExit fullscreen mode

(Note, I useHilt to inject dependencies into my view models, but that's not important for this post)

To add searching to this, I needed to add a few new properties and a couple of functions:

  1. A boolean to toggle whether the search box is visible.
  2. A string to contain the current search term.
  3. Functions to toggle the search box visibility, and to set the search term.

My view model now looked like this:

@HiltViewModelclassProductListViewModel@Injectconstructor(privatevalrepository:Repository):ViewModel(){privateval_search=MutableStateFlow("")valsearch=_search.asStateFlow().stateIn(scope=viewModelScope,started=SharingStarted.WhileSubscribed(),initialValue="",)privateval_isSearchShowing=MutableStateFlow(false)valisSearchShowing=_isSearchShowing.asStateFlow().stateIn(scope=viewModelScope,started=SharingStarted.WhileSubscribed(),initialValue=false,)valproducts=Pager(PagingConfig(pageSize=10,enablePlaceholders=false,)){ProductPagingSource(repository=repository,search=query,)}.flow.cachedIn(viewModelScope)funsetSearch(query:String){_search.value=query}funtoggleIsSearchShowing(){_isSearchShowing.value=!_isSearchShowing.value}}
Enter fullscreen modeExit fullscreen mode

Now we just need to update the paged data when the search term changes. Luckily, this is extremely easy when working with flows as we can use a flow transformation (namelyflatMapLatest) so that when the search term changes a new flow is emitted:

@HiltViewModelclassProductListViewModel@Injectconstructor(privatevalrepository:Repository):ViewModel(){privateval_search=MutableStateFlow("")valsearch=_search.asStateFlow().stateIn(scope=viewModelScope,started=SharingStarted.WhileSubscribed(),initialValue="",)privateval_isSearchShowing=MutableStateFlow(false)valisSearchShowing=_isSearchShowing.asStateFlow().stateIn(scope=viewModelScope,started=SharingStarted.WhileSubscribed(),initialValue=false,)valproductsSearchResults=search.debounce(300.milliseconds).flatMapLatest{query->Pager(PagingConfig(pageSize=10,enablePlaceholders=false,)){ProductPagingSource(repository=repository,search=query,)}.flow.cachedIn(viewModelScope)}funsetSearch(query:String){_search.value=query}funtoggleIsSearchShowing(){_isSearchShowing.value=!_isSearchShowing.value}}
Enter fullscreen modeExit fullscreen mode

We also apply thedebounce transformation so that as the user is typing we don't constantly refresh the paging data. In this case, I set the debounce interval to 300 milliseconds.

All that's left to do is to hook the view model up to a view - an exercise left to the reader, though you cansee my implementation here.

A full sample project isavailable on GitHub, which ties this approach together with dummy product data coming from a web request.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

  • Location
    North East England
  • Work
    Software Engineer
  • Joined

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp