Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Android Jetpack の Paging を用いたリストを再読み込みするまでの長かった道のり

More than 1 year has passed since last update.

やりたいこと

PagedListAdapter をセットした RecyclerView を再度読み込みし直したい。

シチュエーション

例:Material Design > Backdrop スタイルの検索結果一覧画面にて

  • 「検索ワード」が変更されたり「絞り込みの条件」が追加された場合に検索結果一覧をリロードしたい
  • 検索結果一覧が Swipe-to-Refresh された場合

など。

backdrop-shrine-ahero.png

試み

PagedListAdapter を再生成して RecyclerView にセットし直すというようなチャチな発想では全然ダメでした :no_good:

参考

公式の googlesamples/android-architecture-components/PagingWithNetworkSample/ を解読します。

Screenshot_1530550075.png

天才・Googler 様が考える実装はクセがスゴかったです。

仕組み

「検索ワード」や「絞り込みの条件」が変化した場合

ViewModel が保持する検索条件に関する MutableLiveData の値を更新して RecyclerView をリフレッシュしています。

Swipe-to-Refresh した場合

ネットワーク上からデータを取得していれば DataSource.invalidate() を呼び、Room からデータを取得していればネットワーク上からデータを取り直しトランザクション終了後自動的に反映されます。

実践

2018 年 7 月 8 日時点の公式のサンプルは「検索ワード」のみが RecyclerView をリフレッシュするトリガーになっていますが、「検索ワード」と「絞り込みの条件」が変化した場合に検索結果一覧をリロードする方法について考えてみました。

サンプル

  1. 複数ある検索条件を1つにまとめたデータクラス SearchParameter を定義
  2. ViewModelSearchParameterMutableLiveData を保持
  3. 検索条件が変化して検索結果一覧を更新したい場合は MutableLiveData.setValue() を実施します
SearchParameter.kt
/**
 * 複数の検索条件をまとめたデータクラス
 */
data class SearchParameter(
        var keyword: String?, // キーワード
        var minPrice: Int?,   // 価格の下限
        var maxPrice: Int?,   // 価格の上限
        var size: Int?        // 大きさ
)
SearchViewModel.kt
class SearchViewModel(private val repository: SearchRepository) : ViewModel() {

    private val searchParameterMutableLiveData = MutableLiveData<SearchParameter>()

    private val repoResult = map(searchParameterMutableLiveData) { searchParameter ->
        repository.search(searchParameter = searchParameter, pageSize = 20)
    }

    val searchResults = switchMap(repoResult) { it.pagedList }!!

    /**
     * 条件を指定して検索を実施
     */
    fun search(keyword: String?, minPrice: Int?, maxPrice: Int?, size: Int?) {
        searchParameterMutableLiveData.value = SearchParameter(
                keyword = keyword,
                minPrice = minPrice,
                maxPrice = maxPrice,
                size = size)
    }
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away